Je veux savoir quelles sont les bonnes pratiques entre l'utilisation des conditions in tuple
et in list
et savoir pourquoi, comme dans le scénario suivant:
my_variable = 'A' if my_variable in [2, 'A', None]: return True elif my_variable in (2, 'A', None): return True
3 Réponses :
list
et tuple
ont tous deux une complexité en temps O (n) pour les contrôles x dans le conteneur
.
Cependant, set
ont un O (1) pour cette vérification (la plupart du temps, le pire des cas aura une complexité temporelle pire en raison de collisions de hachage).
Voir ces horaires pour une liste, tuple et un ensemble avec 1 million d'éléments:
0.08769642199999961 0.09637485699999981 9.329999999252436e-07
Sorties
from timeit import Timer li = list (range(1, 1000000)) t = tuple(range(1, 1000000)) s = set (range(1, 1000000)) def x_in_list(): 999999 in li def x_in_tuple(): 999999 in t def x_in_set(): 999999 in s print(min(Timer(x_in_list).repeat(5, 5))) print(min(Timer(x_in_tuple).repeat(5, 5))) print(min(Timer(x_in_set).repeat(5, 5)))
Les ensembles
sont moyens cas O (1) (les collusions de hachage signifient que cela pourrait être pire). Cela ne vaut également la peine de créer un ensemble
que si vous faites plusieurs tests dans
(je suis sûr que vous le savez, mais cela vaut la peine de l'épeler en dehors)
@Chris_Rands on parle toujours de cas moyen quand on parle de complexité du temps (par exemple quicksort est toujours considéré comme O (nlogn) même si son pire cas est O (n ^ 2)), mais je vais l'ajouter.
Un tuple
est une séquence immuable, alors qu'une liste
est une séquence mutable, ce qui signifie que les tuples ne peuvent pas être modifiés, mais une liste peut l'être.
Si vous ne voulez pas modifier la structure de données que vous vérifiez dans
, utilisez tuple
, sinon utilisez list, sinon les deux se comportent de la même manière.
if my_variable in set([2, 'A', None]): print(True) #True
La sortie sera
True True
Notez que la liste et le tuple ont une complexité de temps O (n)
à vérifier, à obtenir une complexité O (1)
moyenne, utiliser un ensemble.
my_variable = 'A' if my_variable in [2, 'A', None]: print(True) if my_variable in (2, 'A', None): print(True)
La différence d'exécution est négligeable entre List, Tuple et Set s'il n'y a que 3 éléments.
Le guide de style Pep8 ne dit rien à ce sujet pour autant que je sache, vous pouvez donc utiliser celui que vous préférez.
Quelque chose que les autres réponses ont manqué, en ce qui concerne la lisibilité, c'est que vous pouvez le déclarer un ensemble directement comme celui-ci:
if my_variable in {2, 'A', None}: print(True)
* Techniquement, il y a une différence avec l'utilisation de Set over List ou Tuple - les objets sont comparés au hachage plutôt qu'à l'égalité, définis dans une classe comme __hash__ plutôt que __eq__
un
set
serait le plus efficace ici ...my_variable in set ((2, 'A', None))
. (mais cela en vaut-il vraiment la peine? voir le commentaire ci-dessous ...)C'est une optimisation assez inutile, à mon avis. Ces minuscules ensembles / listes / tuples sont construits, recherchés et détruits très rapidement, donc choisir le plus rapide ne vaut pas la peine
@ForceBru Oui car les conteneurs ne contiennent jamais plus de 3 éléments;)
@Chris_Rands en fait dans mon cas, les conteneurs pourraient être très volumineux, je ne l'ai simplement pas mentionné dans l'exemple.
@getName Je pense que vous avez manqué mon ton sarcastique;)