2017-10-05 5 views
1

Je cherche un moyen rapide de comparer une valeur de dict à toutes les valeurs, et je veux parcourir toutes les valeurs de la dict. Je comprends qu'il y aura beaucoup de répétitions dans la vérification de valeur, donc J'essayais de mettre à jour le itérable (touches pop déjà itératives) pendant l'itération, mais il semble que je ne puisse pas modifier l'itérable pendant l'itération .Comparer une valeur dict à toutes les valeurs large dict pour toutes les valeurs dict

Voici le code que je utilise:

#comparing value to all value2 

duplicates = [] 
for key,value in image_dict_copy.items(): 
    for key2,value2 in image_dict_copy.items(): 
     if hamming_distance(value, value2) > .85: 
      duplicates.append((key, key2)) 
     image_dict_copy.pop(key) #doesn't work 
     print(len(image_dict_copy)) #trying to shrink the size of the iterable 

Toute suggestion quant à la façon d'améliorer la vitesse? C'est assez lent en ce moment.

Répondre

3

Il existe plusieurs façons de faire cela, mais essentiellement, vous voulez comparer toutes les paires de touches possibles dans votre dict. La façon la plus simple est de ne pas réinventer la roue et de itertools utilisation:

import itertools 
for k1, k2 in itertools.combinations(image_dict_copy, 2): 
    if hamming_distance(image_dict_copy[k1], image_dict_copy[k2]) > .85: 
     duplicates.append((k1, k2)) 

Maintenant, la complexité de calcul sera toujours quadratique, mais vous allez faire environ la moitié du nombre de comparaisons réelles.

itertools.combinations est pratique car il faut tout itérable. Mais si vous aviez une séquence, soit une list, c'est la méthode de base pour itérer sur toutes les paires uniques (par index):

>>> keys = list('abcde') 
>>> for i in range(len(keys)): 
...  for j in range(i + 1, len(keys)): 
...   print(keys[i], keys[j]) 
... 
a b 
a c 
a d 
a e 
b c 
b d 
b e 
c d 
c e 
d e 

Vous pouvez utiliser l'approche ci-dessus si vous avez fait quelque chose comme

keys = list(image_dict_copy) 

Mais le bâton avec itertools

Et juste pour le plaisir, si vous vraiment voulait utiliser pop, itérer sur une copie arrière et pop à l'arrière:

>>> keys = list('abcde') 
>>> keys_copy = keys[:-1] 
>>> for k1 in reversed(keys): 
...  for k2 in reversed(keys_copy): 
...   print(k1, k2) 
...  if keys_copy: 
...   _ = keys_copy.pop() 
... 
e d 
e c 
e b 
e a 
d c 
d b 
d a 
c b 
c a 
b a 
+0

Très bonnes choses. Aller tester des outils pour un peu avant d'accepter comme meilleure réponse. – Moondra