Convertir une liste en dictionnaire en Python


191

Disons que j'ai une liste aen Python dont les entrées correspondent à un dictionnaire. Chaque élément pair représente la clé du dictionnaire et l'élément impair suivant est la valeur

par exemple,

a = ['hello','world','1','2']

et j'aimerais le convertir en dictionnaire b, où

b['hello'] = 'world'
b['1'] = '2'

Quelle est la manière syntaxiquement la plus claire pour y parvenir?


Réponses:


272
b = dict(zip(a[::2], a[1::2]))

Si aest grand, vous voudrez probablement faire quelque chose comme ce qui suit, qui ne fait pas de listes temporaires comme ci-dessus.

from itertools import izip
i = iter(a)
b = dict(izip(i, i))

Dans Python 3, vous pouvez également utiliser une compréhension de dict, mais ironiquement, je pense que le moyen le plus simple de le faire sera avec range()et len(), qui serait normalement une odeur de code.

b = {a[i]: a[i+1] for i in range(0, len(a), 2)}

La iter()/izip()méthode est donc probablement la plus pythonique de Python 3, bien que, comme le note EOL dans un commentaire, zip()soit déjà paresseuse dans Python 3, vous n'en avez donc pas besoin izip().

i = iter(a)
b = dict(zip(i, i))

Si vous le voulez sur une seule ligne, vous devrez tricher et utiliser un point-virgule. ;-)


9
… Ou simplement zip(i, i), en Python 3, puisque zip()now renvoie un itérateur.
Eric O Lebigot

5
Notez que Python 2.7.3 a également la compréhension de dict
user1438003

56

Réponse simple

Une autre option (avec l'aimable autorisation d' Alex Martelli - source ):

dict(x[i:i+2] for i in range(0, len(x), 2))

Note connexe

Si vous avez ceci:

a = ['bi','double','duo','two']

et vous voulez ceci (chaque élément de la liste saisissant une valeur donnée (2 dans ce cas)):

{'bi':2,'double':2,'duo':2,'two':2}

vous pouvez utiliser:

>>> dict((k,2) for k in a)
{'double': 2, 'bi': 2, 'two': 2, 'duo': 2}

2
Est-ce uniquement pour Python 3?
Tagar du

2
utiliser fromkeys. >>> dict.fromkeys(a, 2) {'bi': 2, 'double': 2, 'duo': 2, 'two': 2}
Gdogg

1
Cela fait autre chose que ce que la question pose.
ozn

17

Vous pouvez utiliser une compréhension de dict pour cela assez facilement:

a = ['hello','world','1','2']

my_dict = {item : a[index+1] for index, item in enumerate(a) if index % 2 == 0}

Ceci est équivalent à la boucle for ci-dessous:

my_dict = {}
for index, item in enumerate(a):
    if index % 2 == 0:
        my_dict[item] = a[index+1]

10

Quelque chose que je trouve plutôt cool, c'est que si votre liste ne contient que 2 éléments:

ls = ['a', 'b']
dict([ls])
>>> {'a':'b'}

Rappelez-vous que dict accepte tout itérable contenant un itérable où chaque élément de l'itérable doit lui-même être un itérable avec exactement deux objets.


rapide et simple, juste pour ajouter si la liste contient plus de deux éléments, utilisez dict (ls) au lieu de dict ([ls]). par exemple si ls = ['a', 'b', 'c', 'd'] then dict (ls)
ankit tyagi

1
Nice et élégant. 'chaque élément de l'itérable doit lui-même être un itérable avec exactement deux objets.' est le fait clé ici.
Abhijeet

4

Peut-être pas le plus pythonique, mais

>>> b = {}
>>> for i in range(0, len(a), 2):
        b[a[i]] = a[i+1]

10
lire à propos deenumerate
SilentGhost

5
enumerate ne vous permet pas de spécifier une taille de pas, mais vous pouvez utiliser for i, key in enumerate(a[::2]):. Toujours impythonique puisque le constructeur de dict peut faire la plupart du travail ici pour vous
John La Rooy

@SilentGhost, gnibbler: merci beaucoup d'avoir élargi mes horizons! Je ne manquerai pas de l'intégrer autant que possible à l'avenir!
sahhhm

@gnibbler: Pourriez-vous expliquer un peu plus comment l' for i, key in enumerate(a[::2]):approche pourrait fonctionner? Les valeurs de paire résultantes seraient 0 helloet 1 1, et je ne sais pas comment les utiliser pour produire {'hello':'world', '1':'2'}.
martineau

1
@martineau, vous avez raison. Je pense que je dois avoir voulu direenumerate(a)[::2]
John La Rooy

4

Vous pouvez le faire assez rapidement sans créer de tableaux supplémentaires, donc cela fonctionnera même pour de très grands tableaux:

dict(izip(*([iter(a)]*2)))

Si vous avez un générateur a, encore mieux:

dict(izip(*([a]*2)))

Voici le résumé:

iter(h)    #create an iterator from the array, no copies here
[]*2       #creates an array with two copies of the same iterator, the trick
izip(*())  #consumes the two iterators creating a tuple
dict()     #puts the tuples into key,value of the dictionary

cela fera un dictionnaire avec des paires clé et valeur égales ( {'hello':'hello','world':'world','1':'1','2':'2'})
mik

Non, tout fonctionne très bien. Veuillez lire plus attentivement. Il dit: "Si vous avez un générateur a ..." Si vous n'avez pas de générateur, utilisez simplement la première ligne. Le second est une alternative qui serait utile si vous avez un générateur au lieu d'une liste, comme on le ferait la plupart du temps.
topkara

1

Vous pouvez également le faire comme ceci (conversion de chaîne en liste ici, puis conversion en dictionnaire)

    string_list = """
    Hello World
    Goodbye Night
    Great Day
    Final Sunset
    """.split()

    string_list = dict(zip(string_list[::2],string_list[1::2]))

    print string_list


0

Je ne sais pas si c'est pythonique, mais semble fonctionner

def alternate_list(a):
   return a[::2], a[1::2]

key_list,value_list = alternate_list(a)
b = dict(zip(key_list,value_list))

0

essayez ci-dessous le code:

  >>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
  >>> d2
      {'three': 3, 'two': 2, 'one': 1}

0

Vous pouvez également essayer cette approche, enregistrer les clés et les valeurs dans une liste différente, puis utiliser la méthode dict

data=['test1', '1', 'test2', '2', 'test3', '3', 'test4', '4']

keys=[]
values=[]
for i,j in enumerate(data):
    if i%2==0:
        keys.append(j)
    else:
        values.append(j)

print(dict(zip(keys,values)))

production:

{'test3': '3', 'test1': '1', 'test2': '2', 'test4': '4'}

0
{x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}

result : {'hello': 'world', '1': '2'}
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.