Sözlük anahtarlarını Python'da liste olarak nasıl geri gönderebilirim?


779

In Python 2.7 , ben Sözlük alabilir anahtarlarını , değerlerini veya öğeleri liste olarak:

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

Şimdi, Python> = 3.3 , böyle bir şey elde:

>>> newdict.keys()
dict_keys([1, 2, 3])

Yani, bir liste almak için bunu yapmak zorunda:

newlist = list()
for i in newdict.keys():
    newlist.append(i)

Merak ediyorum, Python 3'te bir liste döndürmenin daha iyi bir yolu var mı?


Bu konuyla ilgili ilginç iş parçacığı güvenliği sorunu burada: blog.labix.org/2008/06/27/…
Paul

2
Python için yeniyim ve bana göre, işe yaramaz yeni veri türlerinin bu şekilde çoğalması Python'un en kötü yönlerinden biri. Bu dict_keys veri türü ne işe yarar? Neden bir liste olmasın?
Phil Goetz

Yanıtlar:


975

Deneyin list(newdict.keys()).

Bu, dict_keysnesneyi bir listeye dönüştürür .

Öte yandan, kendinize bunun önemli olup olmadığını sormalısınız. Kodlamanın Pythonic yolu, ördek yazmayı varsaymaktır ( eğer bir ördek gibi görünüyor ve bir ördek gibi quacks, bir ördek ). dict_keysNesne çoğu amaçlar için bir liste gibi hareket edecektir. Örneğin:

for key in newdict.keys():
  print(key)

Açıkçası, araya ekleme işleçleri çalışmayabilir, ancak bu, sözlük anahtarlarının bir listesi için pek bir anlam ifade etmez.


49
newdict.keys () dizin oluşturmayı desteklemiyor
gypaetus

57
list(newdict)ayrıca çalışır (en azından python 3.4'te). .keys()Yöntemi kullanmak için herhangi bir neden var mı ?
31.03.2015

46
Not: pdb> list(newdict.keys()) aynı adda pdb komutuyla çakıştığından hata ayıklayıcıda başarısız olur. pdb> !list(newdict.keys())PDB komutlarından kaçmak için kullanın .
Riaz Rizvi

23
@ naught101 Evet, .keys()neler olduğu konusunda çok daha net.
Felix D.

2
List (newdict.keys ()) kullanırsanız, anahtarların karma sırasına göre onları yerleştirdiğiniz sırada olmadığını unutmayın!
Nate M

277

Python> = 3.5 alternatif: liste hazır bilgisine aç [*newdict]

Python 3.5 ile yeni ambalaj açma genellemeleri (PEP 448) tanıtıldı ve artık kolayca şunları yapabilmenizi sağlıyor:

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]

Paketten çıkarma işlemi yinelenebilir herhangi bir nesneyle *çalışır ve sözlükler yinelendiğinde anahtarlarını döndürdüğü için, liste hazır bilgisi içinde kullanarak kolayca bir liste oluşturabilirsiniz.

Ekleme .keys()ie [*newdict.keys()]bu size bir işlev göz alma ve çağırma mal olacak olsa niyet biraz daha açık yapımında yardımcı olabilir. (dürüst olmak gerekirse, gerçekten endişelenmeniz gereken bir şey değildir ).

*iterableSözdizimi yapıyor benzer list(iterable)ve davranış başlangıçta belgelenmiştir Aramalar bölümünde Python Referans kılavuzun. PEP 448 ile nerede *iterablegörünebileceğine dair kısıtlama, liste, set ve grup değişmezlerine de yerleştirilmesine izin verecek şekilde gevşetildi, İfade listelerindeki referans el kitabı da bunu belirtmek için güncellendi.


list(newdict)Aslında hiçbir işlev çağrısı yapılmadığından daha hızlı (en azından küçük sözlükler için) farkına eşdeğer olsa da :

%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop

%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop

%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop

daha büyük sözlüklerde hız hemen hemen aynıdır (büyük bir koleksiyonda yineleme yükü, bir işlev çağrısının küçük maliyetini azaltır).


Benzer bir şekilde, tuples ve sözlük anahtar kümeleri oluşturabilirsiniz:

>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}

tuple durumda sondaki virgül sakının!


harika bir açıklama, ama lütfen bu "* newdict" sözdizimi türünü açıklayan herhangi bir bağlantıya başvurabilir misiniz, bu sadece ve neden sadece anlamak için sözlükten anahtarları döndürür.Thanx
Muhammad Younus 7:18

1
Bu sözdizimi fonksiyonunda bile Python 2., oldukça zaman mevcut olmuştur @MYounas sen yapabilirsiniz çağrıları def foo(*args): print(args)ardından foo(*{1:0, 2:0})sonuç ile (1, 2)yönlendirilmesi sağlanır. Bu davranış, başvuru kılavuzunun Aramalar bölümünde belirtilmiştir . PEP 448 ile Python 3.5, [*{1:0, 2:0}]bunların kullanılmasına izin verilebilecek yerlerde kısıtlamaları gevşetmiştir . Her iki durumda da cevabımı düzenleyeceğim ve bunları ekleyeceğim.
Dimitris Fasarakis Hilliard

1
*newdict- Bu kesinlikle kod golfçülerinin cevabı; P. Ayrıca: dürüst olmak gerekirse, gerçekten endişelenmeniz gereken bir şey değildir - eğer öyleyse python kullanmayın .
Artemis hala SE'nin

46

list(newdict)Python 2 ve Python 3'te çalışır ve tuşların basit bir listesini sağlar newdict. keys()gerekli değil. (:


26

"Ördek yazarak" tanımında biraz kapalı - dict.keys()liste benzeri bir nesne değil, yinelenebilir bir nesne döndürür. Yinelenebilir bir yerde çalışacak herhangi bir yerde çalışacaktır - bir listenin çalışacağı herhangi bir yer değil. bir liste de yinelenebilir, ancak yinelenebilir bir liste (veya sıra DEĞİLDİR ...)

Gerçek kullanım durumlarında, bir diksiyondaki anahtarlarla ilgili en yaygın şey, aralarında yineleme yapmaktır, bu yüzden mantıklıdır. Ve bir liste olarak onlara ihtiyacınız varsa arayabilirsiniz list().

Çok benzer şekilde zip()- vakaların büyük çoğunluğunda, yinelenir - neden sadece yinelemek ve daha sonra tekrar atmak için yepyeni bir tuples listesi oluştursun?

Bu, her yerde listelerin kopyaları yerine, daha fazla yineleyici (ve jeneratör) kullanmak için python'daki büyük bir eğilimin bir parçasıdır.

dict.keys() Bununla birlikte, anlayışlarla çalışmalı - yazım hataları veya başka bir şey için dikkatlice kontrol edin ... benim için iyi çalışıyor:

>>> d = dict(zip(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes'], [None, None]))
>>> [key.split(", ") for key in d.keys()]
[['Sounder V Depth', 'F'], ['Vessel Latitude', 'Degrees-Minutes']]

2
Kullanmanıza bile gerek yok .keys(); Sözlük nesnedir kendisi iterable ve iterated zaman anahtarları üretir: [key.split(", ") for key in d].
Martijn Pieters

25

Bir liste kavrayışı da kullanabilirsiniz :

>>> newdict = {1:0, 2:0, 3:0}
>>> [k  for  k in  newdict.keys()]
[1, 2, 3]

Veya daha kısa,

>>> [k  for  k in  newdict]
[1, 2, 3]

Not: 3.7 altındaki sürümlerde sipariş garanti edilmez (sipariş hala sadece CPython 3.6 ile bir uygulama detayıdır).


6
Sadece kullan list(newdict). Burada bir liste kavrayışına gerek yoktur.
Martijn Pieters

8

keysYöntemi kullanmadan bir listeye dönüştürmek daha okunabilir hale getirir:

list(newdict)

ve sözlükler arasında dolaşırken aşağıdakilere gerek yoktur keys():

for key in newdict:
    print key

önceden oluşturulmuş anahtarların bir listesini gerektiren döngü içinde değiştirmiyorsanız:

for key in list(newdict):
    del newdict[key]

Python 2'de marjinal bir performans kazancı varkeys() .


8

Anahtarları ayrı ayrı saklamanız gerekiyorsa, Genişletilmiş Yinelenebilir Paket Açma (python3.x +) kullanarak şimdiye kadar sunulan diğer tüm çözümlerden daha az yazmayı gerektiren bir çözüm .

newdict = {1: 0, 2: 0, 3: 0}
*k, = newdict

k
# [1, 2, 3]

            ╒═══════════════╤═════════════════════════════════════════╕
             k = list(d)      9 characters (excluding whitespace)   
            ├───────────────┼─────────────────────────────────────────┤
             k = [*d]         6 characters                          
            ├───────────────┼─────────────────────────────────────────┤
             *k, = d          5 characters                          
            ╘═══════════════╧═════════════════════════════════════════╛

1
İşaret ettiğim tek küçük uyarı kher zaman burada bir liste olmasıdır. Bir kullanıcı bir demet veya anahtarlardan bir set isterse, diğer seçeneklere geri dönmesi gerekir.
Dimitris Fasarakis Hilliard

1
Daha dikkate değer bir not açıklamada olarak, bu gerçektir *k, = dgörünmesini (ama görmek ve belki bu cevabı güncelleyebilirsiniz nerede sınırlamaları vardır, PEP 572 - genişletilmiş açma atm atama ifadeleri desteklenmez ama o birgün olabilir! )
Dimitris Fasarakis Hilliard

anahtarların ve değerlerin listelemesini istiyorsanız ne olur?
endolit

1
@endolith belki keys, vals = zip(*d.items())(bu iki tuple verir, ancak yeterince yakın). Bundan daha kısa bir ifade bilmiyorum.
cs95

1

Anahtarları sözlükten çıkarabileceğimiz 2 yolu düşünebilirim.

Yöntem 1: - .keys () yöntemini kullanarak anahtarları almak ve sonra listeye dönüştürmek için.

some_dict = {1: 'one', 2: 'two', 3: 'three'}
list_of_keys = list(some_dict.keys())
print(list_of_keys)
-->[1,2,3]

Yöntem 2: - Boş bir liste oluşturmak ve daha sonra bir döngü aracılığıyla listeye anahtarları eklemek için. Değerleri bu döngü ile de alabilirsiniz (yalnızca anahtarlar için .keys () ve hem anahtar hem de değer çıkarma için .items () kullanın)

list_of_keys = []
list_of_values = []
for key,val in some_dict.items():
    list_of_keys.append(key)
    list_of_values.append(val)

print(list_of_keys)
-->[1,2,3]

print(list_of_values)
-->['one','two','three']
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.