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?

Mike
la source
3
Possible duplicata de Make dictionary from list with python
Jeru Luke

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. ;-)

kindall
la source
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}
JobJob
la source
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]
Chris Arena
la source
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.

rix
la source
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]
sahhhm
la source
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
Topkara
la source
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
Stefan Gruenwald
la source
1

Je suis également très intéressé d'avoir une ligne unique pour cette conversion, dans la mesure où une telle liste est l'initialiseur par défaut pour le hachage en Perl.

Une réponse exceptionnellement complète est donnée dans ce fil -

Le mien, je suis novice en Python), en utilisant les expressions du générateur Python 2.7 , serait:

dict((a[i], a[i + 1]) for i in range(0, len(a) - 1, 2))

Oleksiy
la source
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))
Manu
la source
0

essayez ci-dessous le code:

  >>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
  >>> d2
      {'three': 3, 'two': 2, 'one': 1}
Muhammed
la source
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'}
Aaditya Ura
la source
0
{x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}

result : {'hello': 'world', '1': '2'}
Mahdi Ghelichi
la source