Sözlük anlamında if / else'i nasıl kullanabilirim?


138

Python 2.7+ sürümünde aşağıdaki gibi bir şey yapmanın bir yolu var mı?

{ something_if_true if condition else something_if_false for key, value in dict_.items() }

Sadece 'eğer' ile her şeyi yapabileceğinizi biliyorum:

{ something_if_true for key, value in dict_.items() if condition}

4
@Marcin anlattığı gibi bir dictyapılır key:valueelemanları, bir bina değil dictburada ama set(bkz dizi değişmezleri ).
mdeous

Yanıtlar:


248

Zaten anladınız: A if test else Bgeçerli bir Python ifadesidir. Dikte anlamanızla ilgili gösterilen tek sorun, bir dikte anlamadaki ifadenin yerinin iki nokta üst üste ile ayrılmış iki ifadeye sahip olması gerektiğidir:

{ (some_key if condition else default_key):(something_if_true if condition
          else something_if_false) for key, value in dict_.items() }

Son ifcümle, koşullu ifadeye sahip olmaktan farklı bir filtre görevi görür.


29
Hem anahtar hem de değer için bir if-else koşuluna sahip olmanız gerekmediğinden bahsetmeye değer. Örneğin {(a if condition else b): value for key, value in dict.items()}çalışacak.
Jeremy Weirich

5
@JeremyWeirich Eğer istemiyorsanız, ikisi için bir if-else'e sahip olmanıza gerek yoktur.
Marcin

@Marcin Anahtar kısım için sadece "if" kullanmam ve değer kısmında hem "if" hem de "else" kullanmam mümkün mü?
nithin11

14

@ Marcin'in cevabı her şeyi kapsar, ancak birisinin gerçek bir örnek görmek istemesi durumunda, aşağıya iki tane ekliyorum:

Aşağıdaki kümeler sözlüğüne sahip olduğunuzu varsayalım

d = {'key1': {'a', 'b', 'c'}, 'key2': {'foo', 'bar'}, 'key3': {'so', 'sad'}}

ve anahtarları dizenin 'a'değerlerde yer alıp almadığını gösteren yeni bir sözlük oluşturmak istiyorsanız,

dout = {"a_in_values_of_{}".format(k) if 'a' in v else "a_not_in_values_of_{}".format(k): v for k, v in d.items()}

hangi verim

{'a_in_values_of_key1': {'a', 'b', 'c'},
 'a_not_in_values_of_key2': {'bar', 'foo'},
 'a_not_in_values_of_key3': {'sad', 'so'}}

Şimdi bunun gibi iki sözlüğünüz olduğunu varsayalım

d1 = {'bad_key1': {'a', 'b', 'c'}, 'bad_key2': {'foo', 'bar'}, 'bad_key3': {'so', 'sad'}}
d2 = {'good_key1': {'foo', 'bar', 'xyz'}, 'good_key2': {'a', 'b', 'c'}}

ve d1anahtarları, d2ilgili değerler aynı ise , anahtarlarla değiştirmek istiyorsanız ,

# here we assume that the values in d2 are unique
# Python 2
dout2 = {d2.keys()[d2.values().index(v1)] if v1 in d2.values() else k1: v1 for k1, v1 in d1.items()}

# Python 3
dout2 = {list(d2.keys())[list(d2.values()).index(v1)] if v1 in d2.values() else k1: v1 for k1, v1 in d1.items()}

hangi verir

{'bad_key2': {'bar', 'foo'},
 'bad_key3': {'sad', 'so'},
 'good_key2': {'a', 'b', 'c'}}

İkinci örnek kullanmak için d1, d2ben olsunAttributeError: 'dict_values' object has no attribute 'index'
alancalvitti

@alancalvitti: Bunu işaret ettiğiniz için teşekkürler! Çözüm Python 2 içindi ve Python 3 için çalışmıyor; Ben de bir Python 3 çözümü ekledim.
Cleb

3

Anahtarlar ve değerler için değerlendirme yapmak için farklı koşullarınız olması durumunda , @ Marcin'in cevabı doğru yoldur.

Anahtarlar ve değerler için aynı koşula sahipseniz, aşağıdakileri besleyen bir jeneratör ifadesinde (anahtar, değer) çiftleri oluşturmak daha iyidir dict():

dict((modify_k(k), modify_v(v)) if condition else (k, v) for k, v in dct.items())

Okuması daha kolaydır ve koşul, anahtar, değer başına yalnızca bir kez değerlendirilir.

@ Cleb'in küme sözlüğü ödünç alma örneği:

d = {'key1': {'a', 'b', 'c'}, 'key2': {'foo', 'bar'}, 'key3': {'so', 'sad'}}

Varsayalım ki, sadece onun keysile sonekini almak istiyorsunuz ve böyle bir durumda setin uzunluğuyla değiştirilmesini istiyorsunuz . Aksi takdirde, anahtar / değer çifti değişmeden kalmalıdır.avaluevalue

dict((f"{k}_a", len(v)) if "a" in v else (k, v) for k, v in d.items())
# {'key1_a': 3, 'key2': {'bar', 'foo'}, 'key3': {'sad', 'so'}}

0

Sözlük anlamada if / else kullanımına başka bir örnek

Kendi ofis işim için veri girişi masaüstü uygulaması üzerinde çalışıyorum ve bu tür veri giriş uygulamalarının tüm girişleri giriş widget'ından alması ve doğrulama veya düzenleme gibi daha ileri işlemler için sözlüğe dökmesi yaygındır. dosyadan giriş widget'larına, vb. seçilen veriler

Geleneksel kodlamayı kullanan ilk tur (8 satır):

entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}

a_dic, b_dic = {}, {}

for field, value in entries.items():
    if field == 'ther':
        for k,v in value.items():
            b_dic[k] = v
        a_dic[field] = b_dic
    else:
        a_dic[field] = value
    
print(a_dic)
 {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”

İkinci turda sözlük anlamayı kullanmaya çalıştım ama döngü hala orada (6 satır):

entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}

for field, value in entries.items():
    if field == 'ther':
        b_dic = {k:v for k,v in value.items()}
        a_dic[field] = b_dic
    else:
        a_dic[field] = value
    
print(a_dic)
 {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”

Son olarak, tek satırlık bir sözlük anlama cümlesiyle (1 satır):

entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}

a_dic = {field:{k:v for k,v in value.items()} if field == 'ther' 
        else value for field, value in entries.items()}
    
print(a_dic)
 {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”

Python 3.8.3 kullanıyorum

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.