Créer un dictionnaire avec compréhension de liste


1280

J'aime la syntaxe de compréhension de la liste Python.

Peut-il également être utilisé pour créer des dictionnaires? Par exemple, en itérant sur des paires de clés et de valeurs:

mydict = {(k,v) for (k,v) in blah blah blah}  # doesn't work

Connexes: collections.Counterest un type de dict spécialisé pour compter les choses: utiliser un dictionnaire pour compter les éléments d'une liste
smci

Réponses:


1898

À partir de Python 2.7 et 3, vous devez simplement utiliser la syntaxe de compréhension de dict :

{key: value for (key, value) in iterable}

Dans Python 2.6 et versions antérieures, la fonction dictintégrée peut recevoir un itérable de paires clé / valeur, vous pouvez donc lui transmettre une compréhension de liste ou une expression de générateur. Par exemple:

dict((key, func(key)) for key in keys)

Cependant, si vous avez déjà des clés et / ou des valeurs itérables, vous n'avez pas du tout besoin d'utiliser une compréhension - c'est plus simple, appelez dictdirectement le intégré:

# consumed from any iterable yielding pairs of keys/vals
dict(pairs)

# "zipped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))

1
que faire si j'ai une liste de mots ['chat', 'chien', 'chat'] et que je veux faire un dict avec clé comme mot et valeur comme compte? Existe-t-il une syntaxe efficace courte pour cela?
cryanbhu

@cryanbhu si ce que vous voulez dire est de compter les répétitions d'un élément donné dans la liste, il y a une classe Counter dans le package de collections: docs.python.org/2/library/collections.html#collections.Counter
fortran

237

Dans Python 3 et Python 2.7+, les compréhensions de dictionnaire ressemblent à ce qui suit:

d = {k:v for k, v in iterable}

Pour Python 2.6 ou version antérieure, voir la réponse de fortran .


57

En fait, vous n'avez même pas besoin d'itérer sur l'itérable s'il comprend déjà une sorte de mappage, le constructeur de dict le fait gracieusement pour vous:

>>> ts = [(1, 2), (3, 4), (5, 6)]
>>> dict(ts)
{1: 2, 3: 4, 5: 6}
>>> gen = ((i, i+1) for i in range(1, 6, 2))
>>> gen
<generator object <genexpr> at 0xb7201c5c>
>>> dict(gen)
{1: 2, 3: 4, 5: 6}

40

En Python 2.7, cela se passe comme:

>>> list1, list2 = ['a', 'b', 'c'], [1,2,3]
>>> dict( zip( list1, list2))
{'a': 1, 'c': 3, 'b': 2}

Fermez-les !


11
Cela ne répond pas du tout à la question.
Jean-François Corbett

32

Créer un dictionnaire avec compréhension de liste en Python

J'aime la syntaxe de compréhension de la liste Python.

Peut-il également être utilisé pour créer des dictionnaires? Par exemple, en itérant sur des paires de clés et de valeurs:

mydict = {(k,v) for (k,v) in blah blah blah}

Vous recherchez l'expression «compréhension du dict» - c'est en fait:

mydict = {k: v for k, v in iterable}

En supposant que blah blah blahc'est un itérable de deux tuples - vous êtes si proche. Créons des "blahs" comme ça:

blahs = [('blah0', 'blah'), ('blah1', 'blah'), ('blah2', 'blah'), ('blah3', 'blah')]

Syntaxe de compréhension des dictés:

Maintenant, la syntaxe est ici la partie de mappage. Ce qui en fait une dictcompréhension au lieu d'une setcompréhension (ce qui est approximatif de votre pseudo-code), c'est le deux-points, :comme ci-dessous:

mydict = {k: v for k, v in blahs}

Et nous voyons que cela a fonctionné, et devrait conserver l'ordre d'insertion à partir de Python 3.7:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah2': 'blah', 'blah3': 'blah'}

En Python 2 et jusqu'à 3.6, l'ordre n'était pas garanti:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah3': 'blah', 'blah2': 'blah'}

Ajout d'un filtre:

Toutes les compréhensions comportent un composant de mappage et un composant de filtrage que vous pouvez fournir avec des expressions arbitraires.

Vous pouvez donc ajouter une partie filtre à la fin:

>>> mydict = {k: v for k, v in blahs if not int(k[-1]) % 2}
>>> mydict
{'blah0': 'blah', 'blah2': 'blah'}

Ici, nous testons simplement si le dernier caractère est divisible par 2 pour filtrer les données avant de mapper les clés et les valeurs.


23

Version Python <2.7 (RIP, 3 juillet 2010 - 31 décembre 2019) , procédez comme suit:

d = dict((i,True) for i in [1,2,3])

Version Python> = 2.7, procédez comme suit:

d = {i: True for i in [1,2,3]}

22

Pour ajouter à la réponse de @ fortran, si vous souhaitez parcourir une liste de clés key_listainsi qu'une liste de valeurs value_list:

d = dict((key, value) for (key, value) in zip(key_list, value_list))

ou

d = {(key, value) for (key, value) in zip(key_list, value_list)}

6

Voici un autre exemple de création de dictionnaire utilisant la compréhension de dict:

Ce que je suis sur le point de faire ici, c'est de créer un dictionnaire alphabétique où chaque paire; est la lettre anglaise et sa position correspondante dans l'alphabet anglais

>>> import string
>>> dict1 = {value: (int(key) + 1) for key, value in 
enumerate(list(string.ascii_lowercase))}
>>> dict1
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9, 'h': 8, 
'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17, 'p': 16, 's': 
19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25, 'x': 24, 'z': 26}
>>> 

Notez l'utilisation d'énumérer ici pour obtenir une liste des alphabets et leurs index dans la liste et permuter les alphabets et les index pour générer la paire de valeurs clés pour le dictionnaire

J'espère que cela vous donne une bonne idée de la composition du dictionnaire et vous encourage à l'utiliser plus souvent pour rendre votre code compact


1
Belle réponse - simplifiée:d = {k: v+1 for v, k in enumerate(string.ascii_lowercase)}
johnnydrama

4

Essaye ça,

def get_dic_from_two_lists(keys, values):
    return { keys[i] : values[i] for i in range(len(keys)) }

Supposons que nous ayons deux listes de pays et de capitaux

country = ['India', 'Pakistan', 'China']
capital = ['New Delhi', 'Islamabad', 'Beijing']

Créez ensuite un dictionnaire à partir des deux listes:

print get_dic_from_two_lists(country, capital)

La sortie est comme ça,

{'Pakistan': 'Islamabad', 'China': 'Beijing', 'India': 'New Delhi'}

9
vous auriez pu utiliser zip
Andre Simon

2
>>> {k: v**3 for (k, v) in zip(string.ascii_lowercase, range(26))}

Python prend en charge les compréhensions dict, qui vous permettent d'exprimer la création de dictionnaires lors de l'exécution en utilisant une syntaxe concise similaire.

Une compréhension de dictionnaire prend la forme {clé: valeur pour (clé, valeur) en itérable}. Cette syntaxe a été introduite dans Python 3 et rétroportée jusqu'à Python 2.7, vous devriez donc pouvoir l'utiliser quelle que soit la version de Python que vous avez installée.

Un exemple canonique prend deux listes et crée un dictionnaire où l'élément à chaque position dans la première liste devient une clé et l'élément à la position correspondante dans la deuxième liste devient la valeur.

La fonction zip utilisée dans cette compréhension renvoie un itérateur de tuples, où chaque élément du tuple est pris à la même position dans chacun des itérables d'entrée. Dans l'exemple ci-dessus, l'itérateur retourné contient les tuples («a», 1), («b», 2), etc.

Production:

{'i': 512, 'e': 64, 'o': 2744, 'h': 343, 'l': 1331, 's': 5832, 'b': 1, 'w': 10648, ' c ': 8,' x ': 12167,' y ': 13824,' t ': 6859,' p ': 3375,' d ': 27,' j ': 729,' a ': 0,' z ' : 15625, «f»: 125, «q»: 4096, «u»: 8000, «n»: 2197, «m»: 1728, «r»: 4913, «k»: 1000, «g»: 216 , 'v': 9261}


2

Ce code créera un dictionnaire en utilisant la compréhension de liste pour plusieurs listes avec des valeurs différentes qui peuvent être utilisées pour pd.DataFrame()

#Multiple lists 
model=['A', 'B', 'C', 'D']
launched=[1983,1984,1984,1984]
discontinued=[1986, 1985, 1984, 1986]

#Dictionary with list comprehension
keys=['model','launched','discontinued']
vals=[model, launched,discontinued]
data = {key:vals[n] for n, key in enumerate(keys)}

enumeratepassera nà valspour correspondre à chacun keyavec sa liste


1

Juste pour jeter un autre exemple. Imaginez que vous ayez la liste suivante:

nums = [4,2,2,1,3]

et vous voulez le transformer en dict où la clé est l'index et la valeur est l'élément dans la liste. Vous pouvez le faire avec la ligne de code suivante:

{index:nums[index] for index in range(0,len(nums))}

0

Vous pouvez créer un nouveau dict pour chaque paire et le fusionner avec le dict précédent:

reduce(lambda p, q: {**p, **{q[0]: q[1]}}, bla bla bla, {})

De toute évidence, cette approche nécessite reducede functools.


même idée: réduire (lambda p, q: {** p, ** dict ([q])}, bla bla bla, {})
Mahmoud Khaled
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.