Saya punya dictyang memiliki banyak entri. Saya hanya tertarik pada beberapa dari mereka. Apakah ada cara mudah untuk memangkas yang lainnya?
Saya punya dictyang memiliki banyak entri. Saya hanya tertarik pada beberapa dari mereka. Apakah ada cara mudah untuk memangkas yang lainnya?
Jawaban:
Membangun dikte baru:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
Menggunakan pemahaman kamus.
Jika Anda menggunakan versi yang tidak memilikinya (yaitu Python 2.6 dan sebelumnya), buatlah dict((your_key, old_dict[your_key]) for ...). Itu sama, meskipun lebih jelek.
Perhatikan bahwa ini, tidak seperti versi jnnnnn, memiliki kinerja yang stabil (hanya bergantung pada jumlah tombol_Anda) untuk old_dictukuran berapa saja. Baik dari segi kecepatan maupun memori. Karena ini adalah ekspresi generator, ia memproses satu item pada satu waktu, dan itu tidak melihat semua item old_dict.
Menghapus semua yang ada di tempat:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
old_dictmengindikasikan bug di tempat lain, dan dalam hal ini saya sangat suka kesalahan untuk hasil diam-diam salah.
Pemahaman dikt sedikit lebih elegan:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems(). .items()membuat daftar lain.
Berikut ini contoh dalam python 2.6:
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
Bagian penyaringan adalah ifpernyataan.
Metode ini lebih lambat daripada jawaban delnan jika Anda hanya ingin memilih beberapa kunci yang sangat banyak.
if key in ('x','y','z')kurasa.
Anda dapat melakukannya dengan proyek fungsi dari saya funcy perpustakaan:
from funcy import project
small_dict = project(big_dict, keys)
Lihat juga pada select_keys .
Kode 1:
dict = { key: key * 10 for key in range(0, 100) }
d1 = {}
for key, value in dict.items():
if key % 2 == 0:
d1[key] = value
Kode 2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
Kode 3:
dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}
Semua bagian dari kinerja kode diukur dengan timeit menggunakan angka = 1000, dan dikumpulkan 1000 kali untuk setiap bagian kode.
Untuk python 3.6 kinerja tiga cara kunci dict filter hampir sama. Untuk python 2.7 kode 3 sedikit lebih cepat.
Lambda satu liner ini harus bekerja:
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
Ini sebuah contoh:
my_dict = {"a":1,"b":2,"c":3,"d":4}
wanted_keys = ("c","d")
# run it
In [10]: dictfilt(my_dict, wanted_keys)
Out[10]: {'c': 3, 'd': 4}
Ini adalah pemahaman daftar dasar yang berulang pada kunci dikte Anda (i in x) dan menampilkan daftar pasangan tuple (kunci, nilai) jika kunci tersebut tinggal dalam daftar kunci yang Anda inginkan (y). Dict () membungkus semuanya menjadi output sebagai objek dict.
setuntuk wanted_keys, tetapi sebaliknya terlihat bagus.
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z')):, ia kembali {'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}seperti yang dimaksudkan.
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}dan hasilnya adalah {}, yang saya anggap sebagai dict kosong.
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))saya mendapatkan: {'0': [1, 3], '2': [1, 4]}yang merupakan hasil yang diinginkan
Diberikan kamus asli Anda origdan sekumpulan entri yang Anda minati keys:
filtered = dict(zip(keys, [orig[k] for k in keys]))
yang tidak sebaik jawaban delnan, tetapi harus bekerja di setiap versi Python yang menarik. Namun, ini rapuh untuk setiap elemen yang keysada di kamus asli Anda.
Berdasarkan jawaban yang diterima oleh delnan.
Bagaimana jika salah satu kunci yang Anda inginkan tidak ada di old_dict? Solusi delnan akan melempar pengecualian KeyError yang dapat Anda tangkap. Jika bukan itu yang Anda butuhkan, mungkin Anda ingin:
hanya sertakan kunci yang ada di old_dict dan kumpulan want_keys Anda.
old_dict = {'name':"Foobar", 'baz':42}
wanted_keys = ['name', 'age']
new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}
>>> new_dict
{'name': 'Foobar'}memiliki nilai default untuk kunci yang tidak disetel di old_dict.
default = None
new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
>>> new_dict
{'age': None, 'name': 'Foobar'}{k: old_dict.get(k, default) for k in ...}
Fungsi ini akan melakukan trik:
def include_keys(dictionary, keys):
"""Filters a dict by only including certain keys."""
key_set = set(keys) & set(dictionary.keys())
return {key: dictionary[key] for key in key_set}
Sama seperti versi delnan, kamus ini menggunakan pemahaman kamus dan memiliki kinerja yang stabil untuk kamus besar (hanya bergantung pada jumlah kunci yang Anda izinkan, dan bukan jumlah total kunci dalam kamus).
Dan seperti versi MyGGan, yang ini memungkinkan daftar kunci Anda untuk memasukkan kunci yang mungkin tidak ada dalam kamus.
Dan sebagai bonus, inilah kebalikannya, di mana Anda dapat membuat kamus dengan mengecualikan kunci tertentu di aslinya:
def exclude_keys(dictionary, keys):
"""Filters a dict by excluding certain keys."""
key_set = set(dictionary.keys()) - set(keys)
return {key: dictionary[key] for key in key_set}
Perhatikan bahwa tidak seperti versi delnan, operasi tidak dilakukan di tempat, sehingga kinerjanya terkait dengan jumlah kunci dalam kamus. Namun, keuntungannya adalah bahwa fungsi ini tidak akan mengubah kamus yang disediakan.
Sunting: Menambahkan fungsi terpisah untuk mengecualikan kunci tertentu dari dikt.
invertmenyiratkan bahwa keysargumen itu dipertahankan, atau bahwa keysargumen itu ditolak?", Berapa banyak dari mereka akan setuju?
Jika kita ingin membuat kamus baru dengan kunci yang dipilih dihapus, kita dapat menggunakan pemahaman kamus
Misalnya:
d = {
'a' : 1,
'b' : 2,
'c' : 3
}
x = {key:d[key] for key in d.keys() - {'c', 'e'}} # Python 3
y = {key:d[key] for key in set(d.keys()) - {'c', 'e'}} # Python 2.*
# x is {'a': 1, 'b': 2}
# y is {'a': 1, 'b': 2}
Pilihan lain:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
Tapi Anda mendapatkan list(Python 2) atau iterator (Python 3) dikembalikan oleh filter(), bukan a dict.
filtereddi dictdan Anda mendapatkan kembali kamus!
Berikut adalah metode sederhana lain yang digunakan deldalam satu liner:
for key in e_keys: del your_dict[key]
e_keysadalah daftar kunci yang akan dikecualikan. Ini akan memperbarui dict Anda daripada memberi Anda yang baru.
Jika Anda ingin keluaran baru, buat salinan salinan sebelum menghapus:
new_dict = your_dict.copy() #Making copy of dict
for key in e_keys: del new_dict[key]
Anda dapat menggunakan python-benedict, ini adalah subclass dict.
Instalasi: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
Ini open-source di GitHub: https://github.com/fabiocaccamo/python-benedict
Penafian: Saya penulis perpustakaan ini.