112 votes

Déterminer si 2 listes ont les mêmes éléments, quel que soit leur ordre?

Désolé pour la simple question, mais j'ai du mal à trouver la réponse.

Lorsque je compare 2 listes, je veux savoir si elles sont "égales" en ce sens qu'elles ont le même contenu, mais dans un ordre différent.

Ex:

 x = ['a', 'b']
y = ['b', 'a']
 

Je veux que x == y évalué à True .

156voto

phihag Points 89765

Vous pouvez simplement vérifier si les multisets avec les éléments de x et y sont égaux:

 import collections
collections.Counter(x) == collections.Counter(y)
 

Si les éléments sont triables, une autre alternative est

 sorted(x) == sorted(y)
 

Si les éléments sont uniques, vous pouvez également convertir en ensembles:

 set(x) == set(y)
 

23voto

Aaron Hall Points 7381

L'inférence à partir de votre exemple:

x = ['a', 'b']
y = ['b', 'a']

que les éléments de la liste ne sera pas répétée (ils sont uniques) ainsi que hashable (chaînes et autres de certains immuable des objets python), les plus directs et efficaces de calcul de réponse utilise Python builtin ensembles, (qui sont sémantiquement comme la mathématique des ensembles, vous pouvez avoir appris à l'école).

set(x) == set(y)

Comme phihag suggère d'abord, dans le cas où ils sont hashable, mais non unique, de la collections.Counter travaille aussi sémantiquement comme un multiset, mais il est beaucoup plus lent:

from collections import Counter
Counter(x) == Counter(y) # avoid this

Utilisation

sorted(x) == sorted(y) 

si les éléments sont peut être commandé. Cela permettrait de prendre en compte la non-uniques ou non hashable circonstances, mais cela pourrait être beaucoup plus lent que l'utilisation de jeux.


Une analyse empirique de l'expérience en conclut que l'on devrait utiliser le jeu, puis triés. Seuls opter pour une Contre si vous avez besoin d'autres choses comme des décomptes ou à une utilisation ultérieure comme un multiset.:

>>> import random
>>> data = [str(random.randint(0, 100000)) for i in xrange(100)]
>>> data2 = data[:]
>>> def fooset(): return set(data) == set(data2)
... 
>>> import collections
>>> def foocount(): return collections.Counter(data) == collections.Counter(data2)
... 
>>> def foosort(): return sorted(data) == sorted(data2)
... 
>>> import timeit
>>> min(timeit.repeat('fooset()', 'from __main__ import fooset, foocount, foosort'))
21.535013914108276
>>> min(timeit.repeat('foocount()', 'from __main__ import fooset, foocount, foosort'))
147.164559841156
>>> min(timeit.repeat('foosort()', 'from __main__ import fooset, foocount, foosort')) 
65.28950691223145

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X