Bir var dict
girdileri bir sürü vardır. Sadece birkaç tanesiyle ilgileniyorum. Diğerlerini budamanın kolay bir yolu var mı?
Bir var dict
girdileri bir sürü vardır. Sadece birkaç tanesiyle ilgileniyorum. Diğerlerini budamanın kolay bir yolu var mı?
Yanıtlar:
Yeni bir diksiyon oluşturmak:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
Sözlük anlamayı kullanır.
Bunlardan yoksun bir sürüm kullanıyorsanız (yani Python 2.6 ve öncesi), yapın dict((your_key, old_dict[your_key]) for ...)
. Aynı şey, daha çirkin olsa da.
Bunun, jnnnnn sürümünün aksine old_dict
, herhangi bir boyutta sabit bir performansa (yalnızca anahtarlarınızın sayısına bağlı olarak) sahip olduğunu unutmayın . Hem hız hem de hafıza açısından. Bu bir üretici ifadesi olduğundan, her seferinde bir öğe işler ve tüm old_dict öğelerine bakmaz.
Her şeyi yerinde kaldırma:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
old_dict
başka bir yerde bir hatayı gösterdiği birçok şey var ve bu durumda sessizce yanlış sonuçlara bir hatayı tercih ederim.
Biraz daha zarif dikseli anlama:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems()
Bunun yerine kullandıysanız muhtemelen aynı mükemmel olurdu . .items()
başka bir liste oluşturur.
İşte python 2.6'daki bir örnek:
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
Filtreleme kısmı if
ifadedir.
Bu yöntem delnan'ın cevabından daha yavaştır, ancak çok fazla tuştan sadece birkaçını seçmek istiyorsanız.
if key in ('x','y','z')
tahmin ediyorum.
Kod 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
Kod 2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
Kod 3:
dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}
Tüm kod performansına bağlı parça sayısı = 1000 kullanılarak timeit ile ölçülür ve her bir kod parçası için 1000 kez toplanır.
Python 3.6 için, filtre dikme tuşlarının üç yolunun performansı neredeyse aynıdır. Python 2.7 için kod 3 biraz daha hızlıdır.
Bu bir astar lambda çalışmalıdır:
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
İşte bir örnek:
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}
Dict anahtarlarınız (i in x) üzerinde yinelenen temel bir liste kavramadır ve anahtar istediğiniz anahtar listenizde (y) yaşıyorsa bir demet (anahtar, değer) çifti listesi çıkarır. Bir dict (), bir dict nesnesi olarak çıktı almak için her şeyi sarar.
set
için kullanmalı wanted_keys
, ancak aksi takdirde iyi görünüyor.
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
gibi geri döner {'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
.
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
ve sonuç, {}
boş bir diksiyon olduğu varsayıldım.
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
şunu elde ederim: {'0': [1, 3], '2': [1, 4]}
amaçlanan sonuç
Orijinal sözlüğünüz orig
ve ilgilendiğiniz girişler kümesi göz önüne alındığında keys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
ki bu delnan'ın yanıtı kadar hoş değil, ancak ilgilenilen her Python sürümünde çalışmalıdır. Bununla birlikte, keys
orijinal sözlüğünüzdeki mevcut öğelerin her birine kırılgandır .
Delnan'ın kabul ettiği cevaba dayanarak.
İstediğiniz anahtarlardan biri eski_dict'ta değilse ne olur? Delnan çözümü, yakalayabileceğiniz bir KeyError istisnası atar. İhtiyacınız olan şey bu değilse belki de yapmak istersiniz:
yalnızca hem eski_dikilde hem de aranan_anahtarlar kümenizde ısrar eden anahtarlar içerir.
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'}
old_dict içinde ayarlanmamış anahtarlar için varsayılan bir değere sahiptir.
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 ...}
Bu işlev hile yapacak:
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}
Delnan'ın sürümü gibi, bu da sözlük anlamayı kullanır ve büyük sözlükler için kararlı bir performansa sahiptir (yalnızca izin verdiğiniz anahtar sayısına bağlıdır, sözlükteki toplam anahtar sayısına bağlı değildir).
MyGGan'ın sürümü gibi, bu da anahtar listenizin sözlükte bulunmayan anahtarları içermesine izin verir.
Ve bonus olarak, orijinaldeki belirli tuşları hariç tutarak sözlük oluşturabileceğiniz tersi:
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}
Delnan'ın versiyonundan farklı olarak, işlemin yerinde yapılmadığından performansın sözlükteki anahtar sayısıyla ilişkili olduğunu unutmayın. Ancak bunun avantajı, işlevin sağlanan sözlüğü değiştirmeyecek olmasıdır.
Düzenle: Belirli anahtarları bir diktenden hariç tutmak için ayrı bir işlev eklendi.
invert
ima ediyor mu?" keys
keys
Seçilen anahtarlar kaldırılmış olarak yeni bir sözlük yapmak istiyorsak, sözlük anlama özelliğini kullanabiliriz
Örneğin:
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}
Başka seçenek:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
Ancak bir list
(Python 2) veya döndürülen bir yineleyici (Python 3) alırsınız, a filter()
değil dict
.
filtered
içinde dict
ve sözlüğünü geri almak!
İşte del
bir astarda kullanılan başka bir basit yöntem :
for key in e_keys: del your_dict[key]
e_keys
hariç tutulacak tuşların listesidir. Size yenisini vermek yerine diktenizi güncelleyecektir.
Yeni bir çıktı diktesi istiyorsanız, silmeden önce diktinin bir kopyasını oluşturun:
new_dict = your_dict.copy() #Making copy of dict
for key in e_keys: del new_dict[key]
Kullanabilirsin python-benedict
, bu dik bir alt sınıf.
Kurulum: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
GitHub'da açık kaynak: https://github.com/fabiocaccamo/python-benedict
Feragatname: Bu kütüphanenin yazarıyım.