Konwertuj listę na słownik w Pythonie


190

Załóżmy, że mam listę aw języku Python, której wpisy są wygodnie mapowane na słownik. Każdy parzysty element reprezentuje klucz do słownika, a następujący nieparzysty element jest wartością

na przykład,

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

i chciałbym przekonwertować go na słownik b, gdzie

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

Jaki jest najczystszy syntaktycznie sposób na osiągnięcie tego?


Odpowiedzi:


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

Jeśli ajest duży, prawdopodobnie będziesz chciał zrobić coś takiego, co nie tworzy tymczasowych list takich jak powyższe.

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

W Pythonie 3 można również użyć rozumienia słownika, ale jak na ironię, myślę, że najprostszym sposobem na to jest użycie range()i len(), który normalnie byłby zapachem kodu.

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

Ta iter()/izip()metoda jest więc prawdopodobnie najbardziej Pythoniczna w Pythonie 3, chociaż jak zauważa EOL w komentarzu, zip()jest już leniwa w Pythonie 3, więc nie potrzebujesz izip().

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

Jeśli chcesz to w jednej linii, będziesz musiał oszukiwać i używać średnika. ;-)


9
… Lub po prostu zip(i, i)w Pythonie 3, ponieważ zip()teraz zwraca iterator.
Eric O Lebigot

5
Zauważ, że Python 2.7.3 również rozumie
dyktowanie

56

Prosta odpowiedź

Inna opcja (dzięki uprzejmości Alexa Martellego - źródło ):

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

Powiązana uwaga

Jeśli masz to:

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

i chcesz tego (każdy element listy wpisujący daną wartość (w tym przypadku 2)):

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

możesz użyć:

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

2
Czy to dotyczy tylko Python 3?
Tagar

2
użyć fromkeys. >>> dict.fromkeys(a, 2) {'bi': 2, 'double': 2, 'duo': 2, 'two': 2}
Gdogg,

1
Robi to coś innego niż pytanie.
ozn

17

W tym celu możesz dość łatwo zrozumieć:

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

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

Jest to równoważne z poniższą pętlą for:

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

10

Coś, co uważam za całkiem fajne, to znaczy, jeśli twoja lista ma tylko 2 elementy:

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

Pamiętaj, że dict akceptuje iterowalność zawierającą iterację, w której każdy element w iteracji musi być iterowalny z dokładnie dwoma obiektami.


szybki i prosty, aby dodać, jeśli lista zawiera więcej niż dwa elementy, użyj dict (ls) zamiast dict ([ls]). na przykład jeśli ls = ['a', 'b', 'c', 'd'], to dict (ls)
ankit tyagi

1
Ładne i eleganckie. „każdy element w iteracji musi sam w sobie iterować dokładnie dwoma obiektami”. jest tutaj kluczowym faktem.
Abhijeet

4

Może nie być najbardziej pytoniczny, ale

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

10
czytaj dalejenumerate
SilentGhost

5
wyliczenie nie pozwala określić rozmiaru kroku, ale możesz użyć for i, key in enumerate(a[::2]):. Wciąż mało mityczne, ponieważ konstruktor nagrań może wykonać dla ciebie większość pracy
John La Rooy

@SilentGhost, gnibbler: wielkie dzięki za poszerzenie moich horyzontów! W przyszłości będę go w miarę możliwości uwzględniał!
sahhhm

@gnibbler: Czy możesz wyjaśnić nieco więcej na temat tego, jak to for i, key in enumerate(a[::2]):podejście może działać? Wynikowe wartości par byłyby 0 helloi 1 1, i nie jest dla mnie jasne, jak ich używać do produkcji {'hello':'world', '1':'2'}.
martineau

1
@martineau, masz rację. Myślę, że musiałem mieć na myślienumerate(a)[::2]
John La Rooy

4

Możesz to zrobić dość szybko, bez tworzenia dodatkowych tablic, więc zadziała to nawet w przypadku bardzo dużych tablic:

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

Jeśli masz generator a, jeszcze lepiej:

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

Oto podsumowanie:

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

spowoduje to utworzenie słownika z równymi parami klucz i wartość ( {'hello':'hello','world':'world','1':'1','2':'2'})
mik

Nie, wszystko działa dobrze. Przeczytaj uważniej. Mówi: „Jeśli masz generator ...” Jeśli nie masz generatora, po prostu użyj pierwszego wiersza. Drugi to alternatywa, która byłaby przydatna, jeśli masz generator zamiast listy, jak zwykle przez większość czasu.
topkara,

1

Możesz to również zrobić w ten sposób (tutaj konwersja ciągu na listę, a następnie konwersja do słownika)

    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

Nie jestem pewien, czy jest to python, ale wydaje się, że działa

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

spróbuj poniżej kodu:

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

0

Możesz także wypróbować to podejście, zapisać klucze i wartości na innej liście, a następnie użyć metody 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)))

wynik:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.