Étant donné un dictionnaire:
res = []
t = [0, 1, 2]
for i in range(len(t):
for j in range(i):
res.append(t[i] * t[j])
Je voudrais créer un nouveau dictionnaire qui calcule le produit des valeurs de d et d .
Voici le résultat dont j'ai besoin:
d = {'a#a': 0, 'a#b': 0, 'a#c': 0, 'b#a' : 0, 'b#b' : 1, 'b#c': 2, 'c#a': 0, 'c#b': 2, 'c#c': 4}
Cependant je ne veux pas avoir ce résultat:
d = {'a#a': 0, 'a#b': 0, 'a#c': 0, 'b#b' : 1, 'b#c': 2, 'c#c': 4}
5 Réponses :
Vous pouvez utiliser une compréhension de dict pour ceci:
d = {'b': 0, 'a': 1, 'c': 2}
dd = {f'{k}#{l}': v*w
for i,(k,v) in enumerate(d.items())
for j,(l,w) in enumerate(d.items())
if i<=j}
>>> {'b#b': 0, 'b#a': 0, 'b#c': 0, 'a#a': 1, 'a#c': 2, 'c#c': 4}
EDIT: Si vous voulez que le résultat soit trié par apparition d'objet dans d:
dd = {f'{k}#{l}': v*w for k,v in d.items() for l,w in d.items() if k<=l}
>>> {'a#a': 0, 'a#b': 0, 'a#c': 0, 'b#b': 1, 'b#c': 2, 'c#c': 4}
Cela ne fonctionne pas si la clé 'a' vient après 'b' .
Que veux-tu dire ? Cela fonctionne parfaitement pour moi même si a vient après b
Je veux dire que vous ne verrez pas 'b # a' dans le dictionnaire de sortie, si dans l'entrée 'a' vient après 'b' parce que la condition échoue.
Pourquoi ne pas utiliser une compréhension de dictionnaire ?
result = {}
for k1 in d:
for k2 in (k for k in d if k >= k1):
result[f"{k1}#{k2}"] = d[k1] * d[k2]
Comme @Austin le note dans une autre réponse, ces deux éléments ne respecteront pas le tri original des clés, donc a # b remplacera b # a même si b a été inséré avant a .
@Acorn L'OP n'a probablement pas besoin de garder l'ordre, il veut juste que chaque paire de clés différentes soit dans le résultat une seule fois (c'est-à-dire soit a # b soit b # a code> mais pas les deux).
Python est livré avec des piles, mais le moyen le plus propre n'est pas toujours évident. Vous avez déjà la fonction que vous souhaitez intégrer dans itertools .
Essayez ceci:
>>> print(result)
{'a#a': 0, 'a#b': 0, 'a#c': 0, 'b#b': 1, 'b#c': 2, 'c#c': 4}
itertools.combinations vous donne toutes les paires sans duplication, itertools.combinations_with_replacement vous donne les paires uniques, y compris celles où les clés sont les mêmes.
Sortie:
import itertools
result = {f'{k1}#{k2}': d[k1]*d[k2]
for k1, k2 in itertools.combinations_with_replacement(d, 2)}
itertools pour le plaisir:
{'a#a': 0, 'a#b': 0, 'a#c': 0, 'b#b': 1, 'b#c': 2, 'c#c': 4}
Sortie:
from itertools import combinations_with_replacement
letter_pairs, number_pairs = (combinations_with_replacement(l, r=2) for l in zip(*d.items()))
result = {letters: number
for letters, number in zip(map('#'.join, letter_pairs),
(a * b for a, b in number_pairs))}
print(result)
Vous pouvez utiliser itertools pour obtenir les combinaisons et former le dictionnaire!
>>> from itertools import combinations_with_replacement
>>> {"{}#{}".format(v1,v2): d[v1]*d[v2] for v1,v2 in combinations_with_replacement(d.keys(),2)}
{'a#c': 0, 'a#b': 0, 'a#a': 0, 'b#b': 1, 'c#c': 4, 'c#b': 2}
Ou aussi simple que pointé par Duncan,
>>> from itertools import combinations
>>>
>>> d
{'a': 0, 'c': 2, 'b': 1}
>>> combinations(d.keys(),2) # this returns an iterator
<itertools.combinations object at 0x1065dc100>
>>> list(combinations(d.keys(),2)) # on converting them to a list
[('a', 'c'), ('a', 'b'), ('c', 'b')]
>>> {"{}#{}".format(v1,v2): (v1,v2) for v1,v2 in combinations(d.keys(),2)} # form a dict using dict comprehension, with "a#a" as key and a tuple of two values.
{'a#c': ('a', 'c'), 'a#b': ('a', 'b'), 'c#b': ('c', 'b')}
>>> {"{}#{}".format(v1,v2): d[v1]*d[v2] for v1,v2 in combinations(d.keys(),2)}
{'a#c': 0, 'a#b': 0, 'c#b': 2} # form the actual dict with product as values
>>> {"{}#{}".format(v1,v2):d[v1]*d[v2] for v1,v2 in list(combinations(d.keys(),2)) + [(v1,v1) for v1 in d.keys()]} # form the dict including the self products!
{'a#c': 0, 'a#b': 0, 'a#a': 0, 'b#b': 1, 'c#c': 4, 'c#b': 2}
p >