J'ai la liste
list1 = [['P', '2.1'], ['C', '4.1'], ['S', '4.2'], ['M' , '5.3'], ['A', '4.1'], ['C', '3.8'], ['C', '3.9'], ['M', '5.2'], ['A' , '4.3'], ['P', '2.3'], ['C', '4.2'], ['A', '4.4']]
et j'ai pour créer un dictionnaire en ajoutant les valeurs d'éléments répétés.
jusqu'à présent, j'ai ceci:
for line in carsList:
model = line[0]
carsDict.update({model:[]})
if model in carsDict:
carsDict[model].append(float(line[1]))
Mais quand j'imprime ce que j'ai, c'est:
{"P": [2.3], "C": [4.2], "S": [4.2], "M": [5.2], "A": [4.4]} p>
Merci.
5 Réponses :
Vous avez effacé la liste à chaque fois en la mettant à jour en une liste vide, vous n'obtiendrez donc que le dernier élément.
for line in carsList:
model = line[0]
if not model in carsDict:
carsDict[model]=0
carsDict[model]+=float(line[1])
# {'A': 12.8, 'P': 4.4, 'C': 16.0, 'M': 10.5, 'S': 4.2}
Voici ce que vous devez faire. Vous créez une nouvelle liste lorsqu'elle n'existe pas, et vous y ajoutez s'il existe déjà une liste.
for line in carsList:
model = line[0]
if not model in carsDict:
carsDict[model]=[]
carsDict[model].append(float(line[1]))
# {'A': [4.1, 4.3, 4.4], 'P': [2.1, 2.3], 'C': [4.1, 3.8, 3.9, 4.2], 'M': [5.3, 5.2], 'S': [4.2]}
Si vous voulez calculer une somme de tous les flottants:
for line in carsList:
model = line[0]
carsDict.update({model:[]}) # It clears out your list every time!
if model in carsDict:
carsDict[model].append(float(line[1]))
Utilisez les collections dict.setdefault
Ex: final
{'A': ['4.1', '4.3', '4.4'],
'C': ['4.1', '3.8', '3.9', '4.2'],
'M': ['5.3', '5.2'],
'P': ['2.1', '2.3'],
'S': ['4.2']}
ou . defaultdict
from collections import defaultdict result = defaultdict(list)
Sortie:
list1 = [['P', '2.1'], ['C', '4.1'], ['S', '4.2'], ['M', '5.3'], ['A', '4.1'], ['C', '3.8'], ['C', '3.9'], ['M', '5.2'], ['A', '4.3'], ['P', '2.3'], ['C', '4.2'], ['A', '4.4']]
result = {}
for k, v in list1:
result.setdefault(k, []).append(v)
print(result)
Chaque fois que vous parcourez la boucle for, vous réinitialisez la valeur de model à une liste vide dans votre carsDict .
ce que vous pouvez faire est:
for line in carsList:
model = line[0]
if model in carsDict:
carsDict[model].append(float(line[1]))
else:
carsDict[model] = [float(line[1])]
Vous pouvez utiliser un collections.defaultdict code > pour regrouper par le premier élément de chaque sous-liste:
from itertools import groupby
list1 = [['P', '2.1'], ['C', '4.1'], ['S', '4.2'], ['M', '5.3'], ['A', '4.1'], ['C', '3.8'], ['C', '3.9'], ['M', '5.2'], ['A', '4.3'], ['P', '2.3'], ['C', '4.2'], ['A', '4.4']]
print({k: [float(x[1]) for x in g] for k, g in groupby(sorted(list1), key=lambda x: x[0])})
# {'A': [4.1, 4.3, 4.4], 'C': [3.8, 3.9, 4.1, 4.2], 'M': [5.2, 5.3], 'P': [2.1, 2.3], 'S': [4.2]}
print({k: sum(float(x[1]) for x in g) for k, g in groupby(sorted(list1), key=lambda x: x[0])})
# {'A': 12.799999999999999, 'C': 16.0, 'M': 10.5, 'P': 4.4, 'S': 4.2}
Si nous ne sommes intéressés que par la somme des flottants, utiliser un defaultdict (float) est probablement plus rapide que de collecter tous les flottants dans une liste puis d'appliquer sum():
d = defaultdict(float)
for x, y in list1:
d[x] += float(y)
print(dict(d))
# {'P': 4.4, 'C': 16.0, 'S': 4.2, 'M': 10.5, 'A': 12.799999999999999}
Notez également que defaultdict est une sous-classe de dict , donc le cast dict () n'est pas nécessaire.
Vous pouvez également trier par le premier élément puis appliquer itertools.groupby :
from collections import defaultdict
list1 = [['P', '2.1'], ['C', '4.1'], ['S', '4.2'], ['M', '5.3'], ['A', '4.1'], ['C', '3.8'], ['C', '3.9'], ['M', '5.2'], ['A', '4.3'], ['P', '2.3'], ['C', '4.2'], ['A', '4.4']]
d = defaultdict(list)
for x, y in list1:
d[x].append(float(y))
print(dict(d))
# {'P': [2.1, 2.3], 'C': [4.1, 3.8, 3.9, 4.2], 'S': [4.2], 'M': [5.3, 5.2], 'A': [4.1, 4.3, 4.4]}
print({k: sum(map(float, v)) for k, v in d.items()})
# {'P': 4.4, 'C': 16.0, 'S': 4.2, 'M': 10.5, 'A': 12.799999999999999}
Les deux solutions ci-dessus montrent comment grouper et obtenir la somme des flottants. La solution groupby est plus lente pour le regroupement car elle utilise le tri O (NLogN) , tandis que la defaultdict regroupe en O (N) heure. Nous pourrions également remplacer key = lambda x: x [0] par operator.itemgetter (0) , ce qui est légèrement plus rapide. Plus d'informations sur la différence de vitesse entre les deux dans cette réponse a>.
J'ai interprété votre question comme signifiant que vous souhaitez additionner les valeurs de chaque clé. Il y a plusieurs façons d'y parvenir. Utiliser un defaultdict est probablement le plus simple:
{'C': 16.0, 'M': 10.5, 'S': 4.2, 'P': 4.4, 'A': 12.799999999999999}
mais vous pouvez également l'implémenter comme une compréhension de dictionnaire:
carsDict = { k : sum(float(l[1]) for l in list1 if l[0] == k) for k in set(l[0] for l in list1) }
print(carsDict)
Dans les deux cas, la sortie est
from collections import defaultdict
carsDict = defaultdict(float)
for l in list1:
carsDict[l[0]] += float(l[1])
print({ k : v for k, v in carsDict.items() })
Ouais, j'ai également recommandé defaultdict (float) . +1
J'ai demandé à OP de clarifier le résultat attendu car toute cette réponse pourrait être erronée. Votre réponse est la meilleure ici (elle a obtenu mon vote de toute façon) car elle couvre les deux bases.
Ouais, je n'étais pas sûr non plus. J'ai pensé que cela ne ferait pas de mal d'inclure les deux cas. J'espère que le PO pourra clarifier :)
Quel est votre résultat attendu?