OVH Cloud OVH Cloud

Accès à une liste triée de doublet

37 réponses
Avatar
Dominique Crétel
Bonjour,

Je débute en Python.
J'ai la liste _triée_ complexe suivante :

lite = ['222', 'bbb', '111', 'aaa', '333', 'ccc', '21456', 'fdfd']
etc.

cela aurait pu être un dictionnaire, mais l'ordre ci-dessus est important.

le nombre d'éléments est bien pair.

il existe un lien entre le 1er élément et le 2ème, le 3ème et le 4ème,
etc...

comment facilement au moyen d'un for balayer la liste ?

j'ai trouvé cela, mais est-ce bien pythonien ?

-----
def do_some_work(k, v):
print k, " => ", v

i = 0
for x in liste:
if (i %% 2 == 0):
k = x
else:
v = x
do_some_work(k, v)
i = i + 1
-----

Merci

7 réponses

1 2 3 4
Avatar
Christophe Cavalaria
tiissa wrote:

Christophe wrote:
En voici une methode beaucoup plus facile à ecrire :)

i = iter(liste)
for elem in zip(i,i): print elem


Plus facile mais sans garantie. zip ne spécifie pas dans quel ordre il
accède aux listes et à leurs éléments mais ta boucle repose dessus.
Par exemple rien n'empêcherait zip de dévider toute la première liste
avant de s'attaquer aux suivantes (rien, sauf la simplicité de
l'implémentation).


zip non mais izip ne ferait pas une chose pareille. L'implementation serait
impossible sinon.

Personnellement, je déconseillerais cette méthode, au profit de
l'itérateur de Laurent ou de la solution de Jean-Sébastien.


L'iterateur est a mon avis aussi la meilleure solution.

Pour ne pas être le seul à ne rien proposer, voilà une solution avec
groupby :

liste = ['a', 1, 'b', 2, 'c', 3]
from itertools import groupby
for _, (k, v) in groupby(enumerate(liste), lambda (i, x) : i/2):
... print k[1], '=>', v[1]



...
a => 1
b => 2
c => 3









Avatar
R12y
Christophe Cavalaria :

Personnellement, je déconseillerais cette méthode, au profit de
l'itérateur de Laurent ou de la solution de Jean-Sébastien.
L'iterateur est a mon avis aussi la meilleure solution.



Moi je vote pour le presque one-line de Bruno :-)

--

http://www.onirik.net/article.php3?id_article7
http://www.maemo.org/platform/docs/howtos/howto_new_application.html
http://www.linuxdevices.com/files/article057/index.html


Avatar
tiissa
Christophe Cavalaria wrote:
tiissa wrote:

Christophe wrote:

En voici une methode beaucoup plus facile à ecrire :)

i = iter(liste)
for elem in zip(i,i): print elem


Plus facile mais sans garantie. zip ne spécifie pas dans quel ordre il
accède aux listes et à leurs éléments mais ta boucle repose dessus.
Par exemple rien n'empêcherait zip de dévider toute la première liste
avant de s'attaquer aux suivantes (rien, sauf la simplicité de
l'implémentation).



zip non mais izip ne ferait pas une chose pareille. L'implementation serait
impossible sinon.


Certes, mais izip ne garantit pas non plus qu'il va accéder à chacun des
itérateurs à chaque fois dans le même ordre ou même simplement dans
l'ordre dont ta méthode a besoin.
Par exemple, izip pourrait inverser à chaque passage l'ordre auquel il
appelle les itérateurs pour essayer d'optimiser l'utilisation du cache
(en appelant en premier ceux dont il s'est servi en dernier en espérant
qu'ils y soient encore).

En fait, ce que je veux dire c'est que pour ne pas dépendre de
l'implémentation de zip ou d'izip, il faut des itérateurs indépendants.
Si tu utilises le même, tu fais des hypothèses implicites sur les ordres
d'appels et donc ça peut changer.


L'iterateur est a mon avis aussi la meilleure solution.



Accessoirement, itertools nous permet d'avoir un itérateur sur le
principe de la solution de Jean-Sébastien :

from itertools import islice, izip
liste = ['a', 1, 'b', 2, 'c', 3]
for k, v in izip(islice(liste, 0, None, 2), islice(liste, 1, None, 2)):
... print k, '=>', v



...
a => 1
b => 2
c => 3







Avatar
Bruno Desthuilliers
Christophe wrote:

Bof, c'est un pattern à connaitre c'est tout ;)



Python m'a seduit car sans connaitre le language, on comprend ce que
l'on lit. Ce genre de "Pattern" à connaitre, c'est louche :)

D'autant plus que cet idiome n'est ici nécessaire qu'en raison d'une

mauvaise structure de données...


Avatar
Bruno Desthuilliers
Christophe Cavalaria :


Personnellement, je déconseillerais cette méthode, au profit de
l'itérateur de Laurent ou de la solution de Jean-Sébastien.


L'iterateur est a mon avis aussi la meilleure solution.



Moi je vote pour le presque one-line de Bruno :-)



Je t'en remercie, mais tu ferais mieux de voter pour une meilleure
structure de données. L'OP n'aurait pas eu à poster s'il était parti
d'une liste de couples, ie:
[(k1, v1), (k2, v2), (kn, vn)]
au lieu de
[k1, v1, k2, v2, kn, vn]



Avatar
Pierre Quentel
Je préfère celle de NicolasP :

for i in xrange(len(liste), 2):
do_some_work(liste[i], liste[i+1])

Seulement 2 lignes, et on comprend ce que ça fait au premier coup
d'oeil, en tous cas plus vite qu'avec toutes les autres réponses

Pierre
Avatar
Dominique Crétel
Merci à tous pour votre aide.
1 2 3 4