Saya seorang pembuat kode C yang mengembangkan sesuatu dengan python. Saya tahu bagaimana melakukan hal berikut di C (dan karenanya dalam logika seperti C yang diterapkan pada python), tapi saya bertanya-tanya apa cara 'Python' untuk melakukannya.
Saya memiliki kamus d, dan saya ingin mengoperasikan sebagian item, hanya mereka yang kuncinya (string) berisi substring tertentu.
yaitu logika C akan menjadi:
for key in d:
if filter_string in key:
# do something
else
# do nothing, continue
Saya membayangkan versi python akan seperti itu
filtered_dict = crazy_python_syntax(d, substring)
for key,value in filtered_dict.iteritems():
# do something
Saya telah menemukan banyak posting di sini tentang memfilter kamus, tetapi tidak dapat menemukan satu pun yang melibatkan hal ini.
Kamus saya tidak bersarang dan saya menggunakan python 2.7
Jawaban:
Bagaimana dengan pemahaman dict :
filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}
Begitu Anda melihatnya, seharusnya sudah cukup jelas, karena terbaca seperti bahasa Inggris dengan cukup baik.
Sintaks ini membutuhkan Python 2.7 atau lebih tinggi.
Di Python 3, hanya ada
dict.items()
, Anda tidakiteritems()
akan menggunakan:filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}
sumber
filtered_dict = {k:d[k] for k in d if filter_string in k}
?d[k]
pencarian.# do something
di komentar, tapi kami menjatuhkan beberapa kunci di sini.iteritems
Python 3? Saya rasa tidak. Jadi, versi saya akan kompatibel, bukan?iteritems
denganitems
, yang sama dengan Python 2.7iteritems
.Pilih apa pun yang paling mudah dibaca dan dipelihara. Hanya karena Anda dapat menuliskannya dalam satu baris tidak berarti Anda harus menuliskannya. Solusi Anda yang ada dekat dengan apa yang akan saya gunakan selain saya akan menggunakan iteritems untuk melewati pencarian nilai, dan saya benci jika saya dapat menghindarinya:
for key, val in d.iteritems(): if filter_string not in key: continue # do something
Namun jika Anda benar-benar menginginkan sesuatu untuk membiarkan Anda mengulang melalui dikt yang difilter maka saya tidak akan melakukan proses dua langkah untuk membangun dikt yang difilter dan kemudian mengulanginya, melainkan menggunakan generator, karena apa yang lebih pythonic (dan mengagumkan) daripada generator?
Pertama, kami membuat generator, dan desain yang bagus mengharuskan kami membuatnya cukup abstrak agar dapat digunakan kembali:
# The implementation of my generator may look vaguely familiar, no? def filter_dict(d, filter_string): for key, val in d.iteritems(): if filter_string not in key: continue yield key, val
Dan kemudian kita dapat menggunakan generator untuk menyelesaikan masalah Anda dengan baik dan rapi dengan kode yang sederhana dan dapat dimengerti:
for key, val in filter_dict(d, some_string): # do something
Singkatnya: generator itu luar biasa.
sumber
Anda dapat menggunakan fungsi filter bawaan untuk memfilter kamus, daftar, dll. Berdasarkan kondisi tertentu.
filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))
Keuntungannya adalah Anda dapat menggunakannya untuk berbagai struktur data.
sumber
items:
harusitem:
dalam definisi lambda.input = {"A":"a", "B":"b", "C":"c"} output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}
sumber
iteritems()
akan menjadi lebih efisien daripadaitems()
.items()
, yang bertindak seperti Python 2.7iteritems
.Jonathon memberi Anda pendekatan menggunakan pemahaman dikt dalam jawabannya . Berikut adalah pendekatan yang berhubungan dengan Anda do sesuatu bagian.
Jika Anda ingin melakukan sesuatu dengan nilai-nilai kamus, Anda tidak memerlukan pemahaman kamus sama sekali:
Saya menggunakan
iteritems(
) karena Anda menandai pertanyaan Anda denganpython-2.7results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k])
Sekarang hasilnya akan ada dalam daftar dengan
some_function
diterapkan ke setiap pasangan kunci / nilai kamus, yang adafoo
di kuncinya.Jika Anda hanya ingin menangani nilai-nilai dan mengabaikan kuncinya, cukup ubah pemahaman daftar:
results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k])
some_function
bisa dipanggil apa saja, jadi lambda juga akan berfungsi:results = map(lambda x: x*2, [v for k,v in a_dict.iteritems() if 'foo' in k])
Daftar bagian dalam sebenarnya tidak diperlukan, karena Anda juga dapat meneruskan ekspresi generator ke peta:
>>> map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2)) [4]
sumber
map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))
- ini akan memberimu[4]
.map
adalah pemahaman daftar.[f(v) for k, v in d.iteritems() if substring in k]
Saya pikir ini jauh lebih mudah dibaca, dan lebih efisien.results = list(starmap(...))
ataufor result in starmap(...): ...
).