Soru Python Sözlük Anlama


Python'da (anahtarlar için) sözlük anlamayı yaratmak mümkün mü?

Liste anlama olmadan, aşağıdaki gibi bir şey kullanabilirsiniz:

l = []
for n in range(1, 11):
    l.append(n)

Bunu liste kavramasına kısaltabiliriz: l = [n for n in range(1, 11)].

Ancak, bir sözlükin anahtarlarını aynı değere ayarlamak istiyorum. Yapabilirim:

d = {}
for n in range(1, 11):
     d[n] = True # same value for each

Bunu denedim:

d = {}
d[i for i in range(1, 11)] = True

Ancak, ben bir SyntaxError üzerinde for.

Buna ek olarak (bu bölüme ihtiyacım yok, sadece merak ediyorum), bir sözlükün anahtarlarını aşağıdaki gibi bir dizi farklı değere ayarlayabilir misiniz?

d = {}
for n in range(1, 11):
    d[n] = n

Bu sözlük anlama ile mümkün mü?

d = {}
d[i for i in range(1, 11)] = [x for x in range(1, 11)]

Bu da bir yükseltir SyntaxError üzerinde for.


319
2018-01-24 17:51


Menşei


Gelecek okuyucuların bilgisi için: NumPy dizileri, yapmaya çalıştığınız şekilde tek bir değere veya değerler listesine birden çok öğe ayarlamanıza izin verir. NumPy'yi kullanmak için bir nedeniniz olmasa da, muhtemelen bu özellik için buna değmez. - David Z


Cevaplar:


Var Python 2.7+ sözlük sözlükleriama denediğiniz gibi çalışmıyorlar. Liste kavraması gibi, bir yeni sözlük; Mevcut bir sözlüğe anahtar eklemek için bunları kullanamazsınız. Ayrıca, anahtar ve değerleri belirtmeniz gerekir, ancak isterseniz, bir kukla değer belirtebilirsiniz.

>>> d = {n: n**2 for n in range(5)}
>>> print d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Hepsini True olarak ayarlamak isterseniz:

>>> d = {n: True for n in range(5)}
>>> print d
{0: True, 1: True, 2: True, 3: True, 4: True}

İstediğin şey, varolan bir sözlükte birden fazla anahtarı bir kerede ayarlamanın bir yoludur. Bunun için doğrudan bir kısayol yok. Gösterdiğin gibi dönebilirsin ya da yeni değerlerle yeni bir dict oluşturmak için sözlük anlamayı kullanabilirsin. oldDict.update(newDict) yeni değerleri eski tarihe birleştirmek.


428
2018-01-24 17:54



FWIW, dict.update aynı zamanda anahtar kelime çiftlerinin yinelenebilirliğini de kabul edebilir dict inşaatçı - mgilson
Tüm değerler aynı olan bir sözlük oluşturursanız, şunu kullanın: dict.fromkeys(). Yani tüm değerleri True, kullan dict.fromkeys(range(5), True). Dikkat et, değer kopyalanmadıBu nedenle, değişken bir değeriniz olduğunda bunu önlemek isteyebilirsiniz; tüm anahtarlar arasında paylaşılacak. - Martijn Pieters♦
Not: Anahtarlar ayrıca bir yöntemin sonucu olabilir: { n*2 : n for n in range(3) } => {0: 0, 2: 1, 4: 2}. Her ikisi de aynı ifadeyle yapılabilir: { n*2 : n*3 for n in range(3) } => { 0: 0, 2: 3, 4: 6 }. - Zaaier


Kullanabilirsiniz dict.fromkeys sınıf metodu ...

>>> dict.fromkeys(range(1, 11), True)
{1: True, 2: True, 3: True, 4: True, 5: True, 6: True, 7: True, 8: True, 9: True, 10: True}

Bu, tüm tuşların aynı değere eşlendiği bir sözlük oluşturmanın en hızlı yoludur.

Bunun yerine değişken nesnelere sahip olmasına dikkat edin:

d = dict.fromkeys(range(10), [])
d[1].append(2)
print(d[2])  # ???

Eğer sen aslında gerek tüm anahtarları başlatmak için defaultdict ayrıca yararlı olabilir:

from collections import defaultdict
d = defaultdict(lambda: True)

İkinci kısma cevap vermek için, dict-anlayışı sadece ihtiyacınız olan şeydir:

{k: k for k in range(10)}

Veya python2.6 için:

dict((k, k) for k in range(10))

Aynı zamanda bir şekilde çalışan akıllı bir alt sınıf da oluşturabilirsiniz. defaultdict eğer geçersiz olursan __missing__:

>>> class KeyDict(dict):
...    def __missing__(self, key):
...       #self[key] = key  # Maybe add this also??? 
...       return key
... 
>>> d = KeyDict()
>>> d[1]
1
>>> d[2]
2
>>> d[3]
3
>>> print(d)
{}

Temiz.


140
2018-01-24 17:53



Durumunda d = defaultdict(lambda: True), lambda'nın True olması (veya olmaması) gerektiğinde gerekli değildir. - rhbvkleef


>>> {i:i for i in range(1, 11)}
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}

22
2018-01-24 17:54





Gerçekten de, iki yineleyici varsa, tuşlara ve diğer değerlere karşılık gelen bir tane varsa, aşağıdakileri de yapabilirsiniz.

keys = ['a', 'b', 'c']
values = [1, 2, 3]
d = dict(zip(keys, values))

vererek

d = {'a': 1, 'b': 2, 'c': 3}


19
2017-08-16 18:03





Dict () komutunu bir liste üzerinde kullanın, bu çözüm, aynı uzunlukta oldukları sürece her listede rasgele değerlere sahip olmanızı sağlar.

i_s = range(1, 11)
x_s = range(1, 11)
# x_s = range(11, 1, -1) # Also works
d = dict([(i_s[index], x_s[index], ) for index in range(len(i_s))])

11
2018-01-24 17:55



Bir yan not olarak, bu aynı şeydir d = dict(zip(i_s,x_s)) - mgilson


Sözlük anlamayı kullanarak bir listedeki kelimelerin ortaya çıkışını sayma örneğini düşünün.

my_list = ['hello', 'hi', 'hello', 'today', 'morning', 'again', 'hello']
my_dict = {k:my_list.count(k) for k in my_list}
print(my_dict)

Ve sonuç

{'again': 1, 'hi': 1, 'hello': 3, 'today': 1, 'morning': 1}

10
2018-02-17 19:51



Bu çok ilginç olmasa da, birden fazla kez 'merhaba' gibi tuşlar sayılırken en verimli değil - FuriousGeorge


Liste kavramanın temel amacı, orijinal listeyi değiştirmeden veya yok etmeden yeni bir liste oluşturarak yeni bir liste oluşturmaktır.

Yazmak yerine

    l = []
    for n in range(1, 11):
        l.append(n)

veya

    l = [n for n in range(1, 11)]

sadece yazmalısın

    l = range(1, 11)

İki üst kod bloğunda, yeni bir liste oluşturuyorsunuz, bunun üzerinden yineleniyorsunuz ve her bir öğeyi geri alıyorsunuz. Liste kopyası oluşturmanın pahalı bir yolu.

Diğer tuşlara göre aynı değere ayarlanmış tüm tuşlarla yeni bir sözlük almak için şunu yapın:

    old_dict = {'a': 1, 'c': 3, 'b': 2}
    new_dict = { key:'your value here' for key in old_dict.keys()}

Bir SyntaxError alıyorsunuz çünkü yazdığınızda

    d = {}
    d[i for i in range(1, 11)] = True

temelde diyorsunuz: "Anahtarımı ayarla" i aralık için (1, 11) 'i True "ve" i aralığında (1, 11) için "geçerli bir anahtar değil, sadece bir sözdizimi hatası. Dicts listeleri anahtar olarak desteklediyse,

    d[[i for i in range(1, 11)]] = True

ve yok

    d[i for i in range(1, 11)] = True

ancak listeler yıkanabilir değildir, bu yüzden bunları dict tuşları olarak kullanamazsınız.


7
2018-01-24 18:53