210 votes

Comment affirmer que deux listes contiennent les mêmes éléments en Python ?

Lorsque j'écris des scénarios de test, j'ai souvent besoin d'affirmer que deux listes contiennent les mêmes éléments sans tenir compte de leur ordre.

J'ai fait cela en convertissant les listes en ensembles.

Y a-t-il un moyen plus simple de procéder ?

EDITAR :

Comme l'a fait remarquer @MarkDickinson, je peux simplement utiliser TestCase.assertItemsEqual .

Note que TestCase.assertItemsEqual Si vous utilisez une version plus ancienne de Python, vous pouvez utiliser unittest2 - un backport des nouvelles fonctionnalités de Python 2.7.

215voto

flazzarini Points 191

À partir de Python 3.2 unittest.TestCase.assertItemsEqual ( doc ) a été remplacé par unittest.TestCase.assertCountEqual ( doc ) qui fait exactement ce que vous recherchez, comme vous pouvez le lire dans le fichier python documentation de la bibliothèque standard . Le nom de cette méthode est quelque peu trompeur, mais elle fait exactement ce que vous recherchez.

a et b ont les mêmes éléments dans le même nombre, indépendamment de leur ordre

Voici un exemple simple qui compare deux listes ayant les mêmes éléments mais dans un ordre différent.

  • en utilisant assertCountEqual le test sera réussi
  • en utilisant assertListEqual le test échouera en raison de la différence d'ordre des deux listes

Voici un petit exemple de script.

import unittest

class TestListElements(unittest.TestCase):
    def setUp(self):
        self.expected = ['foo', 'bar', 'baz']
        self.result = ['baz', 'foo', 'bar']

    def test_count_eq(self):
        """Will succeed"""
        self.assertCountEqual(self.result, self.expected)

    def test_list_eq(self):
        """Will fail"""
        self.assertListEqual(self.result, self.expected)

if __name__ == "__main__":
    unittest.main()

Note complémentaire : Veuillez vous assurer que les éléments des listes que vous comparez sont triables.

58voto

defuz Points 5575

Version légèrement plus rapide de l'implémentation (si vous savez que la plupart des listes de couples auront des longueurs différentes) :

def checkEqual(L1, L2):
    return len(L1) == len(L2) and sorted(L1) == sorted(L2)

Comparaison :

>>> timeit(lambda: sorting([1,2,3], [3,2,1]))
2.42745304107666
>>> timeit(lambda: lensorting([1,2,3], [3,2,1]))
2.5644469261169434 # speed down not much (for large lists the difference tends to 0)

>>> timeit(lambda: sorting([1,2,3], [3,2,1,0]))
2.4570400714874268
>>> timeit(lambda: lensorting([1,2,3], [3,2,1,0]))
0.9596951007843018 # speed up

34voto

Cory Klein Points 5117

Étant donné que

l1 = [a,b]
l2 = [b,a]

En Python >= 3.0

assertCountEqual(l1, l2) # True

En Python >= 2.7 la fonction ci-dessus a été nommée :

assertItemsEqual(l1, l2) # True

En Python < 2.7

import unittest2
assertItemsEqual(l1, l2) # True

Via six module (Toute version de Python)

import unittest
import six
class MyTest(unittest.TestCase):
    def test(self):
        six.assertCountEqual(self, self.l1, self.l2) # True

20voto

inspectorG4dget Points 25092

La conversion de vos listes en ensembles vous indiquera qu'elles contiennent les mêmes éléments. Mais cette méthode ne peut pas confirmer qu'elles contiennent le même nombre de tous les éléments. Par exemple, votre méthode échouera dans ce cas :

L1 = [1,2,2,3]
L2 = [1,2,3,3]

Il est probablement préférable de trier les deux listes et de les comparer :

def checkEqual(L1, L2):
    if sorted(L1) == sorted(L2):
        print "the two lists are the same"
        return True
    else:
        print "the two lists are not the same"
        return False

Notez que cela ne modifie pas la structure/contenu des deux listes. Au contraire, le tri crée deux nouvelles listes

1voto

radeklos Points 147

Besoin de assurer mais vous pouvez comparer les listes par :

ensure([1, 2]).contains_only([2, 1])

Cela ne soulèvera pas d'exception d'affirmation. La documentation de thin est vraiment mince, donc je vous recommande de regarder à Les codes d'assurance sur github

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