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 je dois créer un dictionnaire en ajoutant les valeurs des é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]}

Merci.

1
Nathalie Gómez 8 avril 2020 à 09:20

5 réponses

Vous avez effacé la liste à chaque fois en la mettant à jour dans une liste vide, vous n'obtenez donc que le dernier élément.

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]))

Voilà 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 souhaitez calculer une somme de tous les flottants:

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}
0
Nemo Zhang 8 avril 2020 à 06:30

Vous pouvez utiliser un collections.defaultdict pour regrouper par le premier élément de chaque sous-liste:

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}

Vous pouvez également trier par le premier élément, puis appliquer itertools.groupby:

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}

Les deux solutions ci-dessus montrent comment regrouper et obtenir la somme des flottants. La solution groupby est plus lente pour le regroupement car elle utilise le tri O(NLogN), tandis que les defaultdict groupes en O(N) temps. Nous pourrions également remplacer key=lambda x: x[0] par operator.itemgerrer(0), qui est légèrement plus rapide.

0
RoadRunner 8 avril 2020 à 06:44

Chaque fois que vous exécutez la boucle for, vous réinitialisez la valeur de model dans une liste vide dans votre carsDict.

Ce que vous pouvez faire c'est:

for line in carsList:
    model = line[0]
    if model in carsDict:
        carsDict[model].append(float(line[1]))
    else:
        carsDict[model] = [float(line[1])]
0
Thibauld Croonenborghs 8 avril 2020 à 06:29

J'ai interprété votre question comme signifiant que vous voulez additionner les valeurs pour chaque clé. Vous pouvez y parvenir de plusieurs manières. L'utilisation d'un defaultdict est probablement la plus simple:

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() })

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

{'C': 16.0, 'M': 10.5, 'S': 4.2, 'P': 4.4, 'A': 12.799999999999999}
0
Nick 8 avril 2020 à 06:45

Utilisez dict.setdefault

Ex:

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)

Ou collections.defaultdict

from collections import defaultdict
result = defaultdict(list)

Sortie:

{'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']}
0
Rakesh 8 avril 2020 à 06:28