Bir listeyi Python'da sözlüğe dönüştürme


190

Diyelim ki aPython'da, girişleri sözlüğe uygun bir listem var . Her çift öğe sözlüğün anahtarını temsil eder ve aşağıdaki tek öğe değerdir

Örneğin,

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

ve ben bir sözlüğe dönüştürmek istiyorum b,

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

Bunu başarmanın sözdizimsel olarak en temiz yolu nedir?


Yanıtlar:


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

Büyükse a, muhtemelen aşağıdaki gibi bir şey yapmak isteyeceksiniz, bu da yukarıdaki gibi geçici listeler yapmaz.

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

Python 3 de dict anlama kullanabilirsiniz, ancak ironik bunun birlikte olacak yapmanın en kolay yolu düşünmek range()ve len()normalde bir kod koku olacağını.

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

Bu nedenle, iter()/izip()yöntem hala Python 3'teki en Pythonic'tir, ancak bir yorumda EOL notları zip()olduğu gibi Python 3'te zaten tembeldir, bu yüzden ihtiyacınız yoktur izip().

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

Bir satırda istiyorsanız, hileli ve noktalı virgül kullanmanız gerekir. ;-)


9
… Ya da basitçe zip(i, i), Python 3'te zip()şimdi bir yineleyici döndürüyor.
Eric O Lebigot

5
Python
2.7.3'ün

56

Basit cevap

Başka bir seçenek ( Alex Martelli'nin izniyle - kaynak ):

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

İlgili not

Eğer buna sahipseniz:

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

ve bunu istediğinizde (listenin her bir öğesi belirli bir değeri girer (bu durumda 2)):

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

kullanabilirsiniz:

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

2
Bu sadece Python 3 için mi?
Tagar

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

1
Bu, sorunun sorduğundan başka bir şey yapıyor.
ozn

17

Bunun için bir diksiyon anlama kullanabilirsiniz:

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

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

Bu, aşağıdaki for döngüsüne eşdeğerdir:

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

10

Listeniz sadece 2 öğe uzunluğunda ise, oldukça havalı bulduğum bir şey:

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

Unutmayın, dict, yinelemedeki her öğenin kendisinin tam olarak iki nesne ile yinelenebilir olması gerektiği bir yinelenebilir içeren tüm yinelemeleri kabul eder.


hızlı ve basit bir, sadece liste ikiden fazla öğe içeriyorsa eklemek için dict (ls) yerine dict (ls) kullanın. örneğin, eğer ls = ['a', 'b', 'c', 'd'] sonra (ls)
ankit tyagi

1
Güzel ve şık. 'yinelenebilir öğedeki her öğenin kendisi tam olarak iki nesne içeren bir yinelenebilir olmalıdır.' buradaki anahtar gerçektir.
Abhijeet

4

En pitonik olmayabilir, ama

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

10
hakkında okumakenumerate
SilentGhost

5
enumerate, bir adım boyutu belirtmenize izin vermez, ancak kullanabilirsiniz for i, key in enumerate(a[::2]):. Dict yapıcısı sizin için burada çalışmanın çoğunu yapabildiğinden hala unpythonic
John La Rooy

@SilentGhost, gnibbler: ufkumu genişlettiğiniz için çok teşekkürler! Gelecekte mümkün olduğunca dahil edeceğimden emin olacağım!
sahhhm

@gnibbler: for i, key in enumerate(a[::2]):Yaklaşımın nasıl işleyebileceği hakkında biraz daha bilgi verebilir misiniz? Ortaya çıkan çift değerleri olacak 0 hellove 1 1bunları üretmek için nasıl kullanacağım açık değil {'hello':'world', '1':'2'}.
martineau

1
@martineau, haklısın. Sanırım demek istedimenumerate(a)[::2]
John La Rooy

4

Ekstra diziler oluşturmadan oldukça hızlı yapabilirsiniz, bu nedenle çok büyük diziler için bile çalışır:

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

Bir jeneratörünüz varsa a, daha da iyisi:

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

İşte yıkık:

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

Bu eşit anahtar ve değer çiftleri ile bir sözlük yapacak ( {'hello':'hello','world':'world','1':'1','2':'2'})
mik

Hayır, hepsi iyi çalışıyor. Lütfen daha dikkatli okuyun. Diyor ki: "Bir jeneratörünüz varsa ..." Bir jeneratörünüz yoksa, sadece ilk satırı kullanın. İkincisi, bir liste yerine bir jeneratörünüz varsa, çoğu zaman olduğu gibi yararlı olacak bir alternatiftir.
topkara

1

Bunu şu şekilde de yapabilirsiniz (dönüşümleri burada listelemek, ardından bir sözlüğe dönüştürmek)

    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

Bunun pitonik olup olmadığından emin değilim, ama işe yarıyor gibi görünüyor

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

aşağıdaki kodu deneyin:

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

0

Ayrıca bu yaklaşımı, anahtarları ve değerleri farklı listeye kaydetmeyi deneyebilir ve ardından dict yöntemini kullanabilirsiniz.

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

çıktı:

{'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'}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.