247 votes

Python création d'un dictionnaire de listes

Je veux créer un dictionnaire dont les valeurs sont des listes. Par exemple:

{1: ['1'], 2: ['1', '2'], 3: ['2']}

Si je fais:

d = dict()
a = ['1', '2']
for i in a:
    for j in range(int(i), int(i) + 2): 
        d[j].append(i)

Je reçois un KeyError, parce que d[...] n'est pas une liste. Dans ce cas, je peux ajouter le code suivant après la cession de l'un à initialiser le dictionnaire.

for x in range(1, 4):
    d[x] = list()

Est-il une meilleure façon de le faire? Disons que je ne connais pas les clés, je vais avoir besoin jusqu'à ce que je suis dans le deuxième for boucle. Par exemple:

class relation:
    scope_list = list()
...
d = dict()
for relation in relation_list:
    for scope_item in relation.scope_list:
        d[scope_item].append(relation)

Une alternative serait alors de remplacer

d[scope_item].append(relation)

avec

if d.has_key(scope_item):
    d[scope_item].append(relation)
else:
    d[scope_item] = [relation,]

Quelle est la meilleure façon de gérer cela? Idéalement, ajoutant serait "juste travail". Est-il une façon d'exprimer que je veux un dictionnaire vide des listes, même si je ne connais pas toutes les touches lorsque j'ai d'abord créer la liste?

315voto

bernie Points 44206

Vous pouvez utiliser defaultdict:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for i in a:
...   for j in range(int(i), int(i) + 2):
...     d[j].append(i)
...
>>> d
defaultdict(<type 'list'>, {1: ['1'], 2: ['1', '2'], 3: ['2']})
>>> d.items()
[(1, ['1']), (2, ['1', '2']), (3, ['2'])]

60voto

Nadia Alramli Points 40381

Vous pouvez le construire avec la compréhension de liste comme ceci:

>>> dict((i, range(int(i), int(i) + 2)) for i in ['1', '2'])
{'1': [1, 2], '2': [2, 3]}

Et pour la deuxième partie de votre question, utilisez defaultdict

>>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
        d[k].append(v)

>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

42voto

RichieHindle Points 98544

Utiliser setdefault:

d = dict()
a = ['1', '2']
for i in a:
    for j in range(int(i), int(i) + 2): 
        d.setdefault(j, []).append(i)

print d  # prints {1: ['1'], 2: ['1', '2'], 3: ['2']}

Assez bizarrement nommé setdefault fonction dit "Obtenir la valeur avec cette clé, ou si cette clé n'existe pas, ajoutez cette valeur, puis le retourner."

Edit: Comme d'autres l'ont souligné à juste titre, defaultdict est une meilleure et plus moderne choix. setdefault est toujours utile dans les anciennes versions de Python (avant 2.5).

2voto

spiffyman Points 138

Votre question a déjà été posée, mais SI vous pouvez remplacer des lignes comme:

if d.has_key(scope_item):

avec:

if scope_item in d:

C'est, d références d.keys() dans la construction. Parfois, defaultdict n'est pas la meilleure option (par exemple, si vous voulez exécuter plusieurs lignes de code après l' else associée à la ci-dessus if), et je trouve l' in syntaxe plus facile à lire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X