Parcourir une liste par paires ou 2 à 2 est une question qui revient souvent (comme dans lire des termes 2 à 2).
Les solutions proposées sont intéressantes et variées.
Mais comme j'ai l'habitude de travailler avec des points (x,y), des lignes (une ligne est composée de deux points ((x1,x1), (x2, y2)) ou de plusieurs) et des polygones (avec un SIG),et que j'ai plusieurs milliers de point ou de lignes à traiter, je vous soumets quelques solutions que j'utilise tous les jours.
Elles sont simples et basées sur des itérateurs/générateurs qui ne saturent pas la mémoire grâce à l'opérateur yield.
Elles ont été glanées de-ci de-là et adaptées au fil du temps (surtout à partir des solutions proposées sur http://stackoverflow.com/)
Tout d'abord le découpage d'une liste en n éléments en utilisant islice
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 # liste originale points = ((1,2),(3,4),(5,6),(7,8))
Vous pouvez aussi le faire beaucoup plus simplement, sans itertools:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 from itertools import islice def decoupe_liste(liste, n): i = iter(liste) elem = list(islice(i, n)) while elem: yield elem elem = list(islice(i, n)) for i in decoupe_liste(points,2): print i [(1, 2), (3, 4)] [(5, 6), (7, 8)] for i in decoupe_liste(points,3): print i [(1, 2), (3, 4), (5, 6)] [(7, 8)]
Mais la plupart du temps, comme je veux créer une ligne continue à partir des points, c'est à dire, segment(point1,point2),segment(point2, point3), etc.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 def decoupe_liste(liste, n): # extrait n élément successifs d'une liste for i in xrange(0, len(liste), n): yield liste[i:i+n] for i in decoupe_liste(points,2): print i ((1, 2), (3, 4)) ((5, 6), (7, 8)) for i in decoupe_liste(points,3): print i ((1, 2), (3, 4), (5, 6)) ((7, 8),)
Parcours d'une liste par paires
C'est aussi valable dans la question posée dans lire des termes 2 à 2
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 def paires(liste): #parcours d'une liste par paires for i in range(1, len(liste)): yield liste[i-1], liste[i] for i, j in paires(points): print i, j (1, 2) (3, 4) (3, 4) (5, 6) (5, 6) (7, 8)
Et les variations sont infinies...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 chaine= "abcdefghij" for i,j in paires(Chaine): print i, j a b b c c d d e e f f g g h h i i j
paires prédécesseur - successeur dans un liste
prédécesseur, courant, successeur dans la liste
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 def paires_pred(liste): # parcours d'une liste par paires pred - successeur prev = None for elem in iterable: yield prev, elem prev = elem for i in paires_pred(points): print i (None, (1, 2)) ((1, 2), (3, 4)) ((3, 4), (5, 6)) ((5, 6), (7, 8))
parcours d'une liste par éléments- liste des autres éléments
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 def voisinage(liste): #parcours d'une liste par triplet prédécesseur -courant- successeur iterateur = iter(liste) pred = None elem = iterateur.next() for next in iterateur: yield (pred,courant,suivant) pred = elem elem = suivant yield (pred,elem,None) # application for pred,courant,suivant in voisinage(points): print pred,courant, suivant None (1, 2) (3, 4) (1, 2) (3, 4) (5, 6) (3, 4) (5, 6) (7, 8) (5, 6) (7, 8) None
combinaison de 2 listes par paires
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 def iter_sur_autres(liste): for index, elem in enumerate(liste): yield elem, liste[:index] + liste[index+1:] for elem, autres in iter_sur_autres(points): print elem, autres (1, 2) ((3, 4), (5, 6), (7, 8)) (3, 4) ((1, 2), (5, 6), (7, 8)) (5, 6) ((1, 2), (3, 4), (7, 8)) (7, 8) ((1, 2), (3, 4), (5, 6))
Les autres solutions sont toujours les bienvenues...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 points2 = ((10,12),(14,15),(16,17),(18,20)) def grid_objects(alist, blist): for i in range(len(alist)): for j in range(len(alist[i])): yield(alist[i][j], blist[i][j]) for (x, y) in grid_objects(points, points2): print (x,y) (1, 10) (2, 12) (3, 14) (4, 15) (5, 16) (6, 17) (7, 18) (8, 20)
Partager