Je codais un problème d'Euler et je me suis heurté à une question qui a éveillé ma curiosité. J'ai deux extraits de code. L'un est avec des listes les autres dictionnaires d'utilisations.
en utilisant des listes :
n=100000
num=[]
suma=0
for i in range(n,1,-1):
tmp=Tuple(set([n for n in factors(i)]))
if len(tmp) != 2: continue
if tmp not in num:
num.append(tmp)
suma+=i
utilisation de dictionnaires :
n=100000
num={}
suma=0
for i in range(n,1,-1):
tmp=Tuple(set([n for n in factors(i)]))
if len(tmp) != 2: continue
if tmp not in num:
num[tmp]=i
suma+=i
Je ne suis préoccupé que par la performance. Pourquoi le deuxième exemple utilisant des dictionnaires est-il incroyablement rapide, plus rapide que le premier exemple avec des listes. l'exemple avec les dictionnaires est presque trente fois plus rapide!
J'ai testé ces 2 codes en utilisant n = 1000000, et le premier code a fonctionné en 1032 secondes et le second en 3,3 secondes, amazin '!
En Python, la complexité temporelle moyenne d'une recherche de clé de dictionnaire est O (1), car elles sont implémentées sous forme de tables de hachage. La complexité temporelle de la recherche dans une liste est en moyenne de O(n). Dans votre code, cela fait une différence dans la ligne if tmp not in num:
, car dans le cas d'une liste, Python doit chercher dans toute la liste pour détecter une appartenance, alors que dans le cas dict, cela ne fait rien sauf dans le pire des cas.
Pour plus de détails, consultez TimeComplexity .
S'il s'agit de rapidité, vous ne devriez créer aucune liste:
n = 100000
factors = ((frozenset(factors(i)), i) for i in range(2, n+1))
num = {k:v for k,v in factors if len(k)==2}
suma = sum(num.values())
Dans une liste, le code if tmp not in num:
est O (n), alors que c'est O(lgn) dans dict.
Edit : Le dict est basé sur le hachage, il est donc beaucoup plus rapide que la recherche dans la liste des doublures .
Je suis presque certain que la "sauce magique" utilisant un dictionnaire réside dans le fait qu'il est composé de paires clé-> valeur.
dans une liste, vous avez affaire à des tableaux, ce qui signifie que la boucle for doit commencer à l’index 0 de votre liste afin de parcourir tous les enregistrements.
le dictionnaire n'a plus qu'à trouver la paire clé-> valeur en question lors du premier "aller-retour" et la renvoyer, d'où la vitesse ...
fondamentalement, tester l'appartenance à un ensemble de paires clé-> valeur est beaucoup plus rapide que de chercher une liste entière. plus votre liste est longue, plus elle ralentit ... mais ce n'est pas toujours le cas, il existe des scénarios dans lesquels une liste sera plus rapide ... mais je pense que c'est peut-être la réponse que vous cherchez