Quel est le coût de len()
pour Python intégré? (Liste/tuple/chaîne/dictionnaire))
C'est O (1) (temps constant, ne dépendant pas de la longueur réelle de l'élément - très rapide) pour chaque type mentionné, plus set
et d'autres tels que array.array
.
Appeler len () sur ces types de données est O(1) dans CPython , l’implémentation la plus courante du langage Python. Voici un lien vers une table qui fournit la complexité algorithmique de nombreuses fonctions différentes dans CPython:
Tous ces objets gardent une trace de leur propre longueur. Le temps nécessaire pour extraire la longueur est petit (O (1) en notation big-O) et consiste principalement en [description brute, écrite en Python, pas termes C]]: recherchez "len "dans un dictionnaire et l'envoyer à la fonction built_in len qui recherchera l'objet __len__
méthode et appelez cela ... tout ce qu’il a à faire est return self.length
Les mesures ci-dessous fournissent la preuve que len()
est O(1) pour les structures de données fréquemment utilisées.
Une note concernant timeit
: lorsque l'indicateur -s
Est utilisé et que deux chaînes sont passées à timeit
, la première chaîne n'est exécutée qu'une seule fois et n'est pas chronométrée.
$ python -m timeit -s "l = range(10);" "len(l)"
10000000 loops, best of 3: 0.0677 usec per loop
$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 loops, best of 3: 0.0688 usec per loop
$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 loops, best of 3: 0.0712 usec per loop
$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 loops, best of 3: 0.0699 usec per loop
$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 loops, best of 3: 0.0686 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 loops, best of 3: 0.0711 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 loops, best of 3: 0.0727 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 loops, best of 3: 0.0682 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 loops, best of 3: 0.0753 usec per loop
$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 loops, best of 3: 0.0754 usec per loop
$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
len est un O(1) car dans votre RAM, les listes sont stockées sous forme de tables (série d'adresses contiguës). Pour savoir quand la table s'arrête, l'ordinateur a besoin de deux choses: longueur et point de départ, c’est pourquoi len () est un O (1), l’ordinateur enregistre la valeur, il suffit donc de la rechercher.
Je pensais à len () dans Python dépend de la taille de la liste, je stocke donc toujours la longueur dans une variable si j'utilise plusieurs fois. Mais aujourd'hui, lors du débogage, j'ai remarqué __len__ attribut dans l'objet list, donc len () doit simplement le récupérer, ce qui rend la complexité O 1. Alors j'ai cherché dans Google si quelqu'un l'a déjà demandé et qu'il est tombé sur ce message.