ฉันมีรายการdict
ที่มีทั้งรายการ ฉันสนใจเพียงบางส่วนเท่านั้น มีวิธีง่าย ๆ ในการตัดออกอื่น ๆ ทั้งหมดหรือไม่
ฉันมีรายการdict
ที่มีทั้งรายการ ฉันสนใจเพียงบางส่วนเท่านั้น มีวิธีง่าย ๆ ในการตัดออกอื่น ๆ ทั้งหมดหรือไม่
คำตอบ:
การสร้าง dict ใหม่:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
ใช้ความเข้าใจในพจนานุกรม
หากคุณใช้เวอร์ชันที่ไม่มีเวอร์ชัน (เช่น Python 2.6 และรุ่นก่อนหน้า) ให้สร้างdict((your_key, old_dict[your_key]) for ...)
ขึ้นมา มันเหมือนกันแม้ว่าจะไม่เป็นที่น่าพอใจ
โปรดทราบว่าสิ่งนี้แตกต่างจากเวอร์ชันของ jnnnnn ที่มีประสิทธิภาพที่มั่นคง (ขึ้นอยู่กับจำนวนของ your_keys) สำหรับold_dict
s ทุกขนาด ทั้งในเรื่องของความเร็วและความจำ เนื่องจากนี่เป็นนิพจน์ตัวสร้างจึงประมวลผลทีละรายการและจะไม่ตรวจสอบรายการทั้งหมดของ old_dict
การลบทุกอย่างในสถานที่:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
old_dict
ระบุข้อผิดพลาดที่อื่นและในกรณีนั้นฉันชอบข้อผิดพลาดมากกับผลลัพธ์ที่ไม่ถูกต้อง
ความเข้าใจในประโยค dict ที่สง่างามกว่าเล็กน้อย:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems()
แทน .items()
สร้างรายการอื่น
นี่คือตัวอย่างใน python 2.6:
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
ส่วนการกรองคือif
คำสั่ง
วิธีนี้ช้ากว่าคำตอบของ delnan หากคุณต้องการเลือกปุ่มจำนวนมากเท่านั้น
if key in ('x','y','z')
ฉันเดา
คุณสามารถทำได้ด้วยฟังก์ชั่นโครงการจากห้องสมุดfuncyของฉัน:
from funcy import project
small_dict = project(big_dict, keys)
ดูที่select_keysด้วย
รหัส 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
รหัส 2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
รหัส 3:
dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}
ประสิทธิภาพของรหัสทั้งหมดจะถูกวัดด้วย timeit โดยใช้หมายเลข = 1,000 และรวบรวม 1,000 ครั้งสำหรับรหัสแต่ละชิ้น
สำหรับไพ ธ อน 3.6 ประสิทธิภาพของปุ่มกดตัวกรองสามวิธีเกือบเหมือนกัน สำหรับ python 2.7 code 3 นั้นเร็วกว่าเล็กน้อย
แลมบ์ดาซับวันนี้ควรทำงาน:
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
นี่คือตัวอย่าง:
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 ของคุณ (i ใน x) และส่งออกรายการของ tuple (คีย์, ค่า) จับคู่ถ้าคีย์อยู่ในรายการคีย์ที่ต้องการ (y) Dict () ล้อมทุกสิ่งเพื่อส่งออกเป็นวัตถุ Dict
set
สำหรับwanted_keys
แต่อย่างอื่นดูดี
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
มันกลับมา{'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
ตามที่ตั้งใจไว้
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
และผลลัพธ์ก็คือ{}
ซึ่งฉันคิดว่าเป็นพจน์ว่างเปล่า
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
ฉันจะได้รับ: {'0': [1, 3], '2': [1, 4]}
ซึ่งเป็นผลลัพธ์ที่ตั้งใจ
ให้พจนานุกรมต้นฉบับของคุณorig
และชุดรายการที่คุณสนใจkeys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
ซึ่งไม่ดีเท่าคำตอบของ delnan แต่ควรใช้ได้ในทุกเวอร์ชั่นที่น่าสนใจ อย่างไรก็ตามมันเปราะบางต่อองค์ประกอบkeys
ที่มีอยู่ในพจนานุกรมต้นฉบับของคุณ
ตามคำตอบที่ยอมรับโดย delnan
เกิดอะไรขึ้นถ้าคีย์ที่คุณต้องการไม่อยู่ใน old_dict โซลูชัน delnan จะส่งข้อยกเว้น KeyError ที่คุณสามารถตรวจจับได้ หากนั่นไม่ใช่สิ่งที่คุณต้องการบางทีคุณอาจต้องการ:
รวมเฉพาะกุญแจที่มีให้ทั้งใน old_dict และชุดที่ต้องการของคุณ
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
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 ...}
ฟังก์ชั่นนี้จะทำการหลอกลวง:
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 พจนานุกรมนี้ใช้ความเข้าใจในพจนานุกรมและมีประสิทธิภาพการทำงานที่มั่นคงสำหรับพจนานุกรมขนาดใหญ่ (ขึ้นอยู่กับจำนวนของคีย์ที่คุณอนุญาตเท่านั้นและไม่รวมถึงจำนวนคีย์ทั้งหมดในพจนานุกรม)
และเช่นเดียวกับรุ่น MyGGan อันนี้อนุญาตให้รายการคีย์ของคุณรวมคีย์ที่อาจไม่มีอยู่ในพจนานุกรม
และเป็นโบนัสนี่คือสิ่งที่ตรงกันข้ามที่คุณสามารถสร้างพจนานุกรมได้โดยไม่รวมคีย์บางตัวในต้นฉบับ:
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 การดำเนินการไม่ได้เกิดขึ้นดังนั้นประสิทธิภาพจึงสัมพันธ์กับจำนวนของคีย์ในพจนานุกรม อย่างไรก็ตามข้อดีของการทำเช่นนี้คือฟังก์ชั่นจะไม่แก้ไขพจนานุกรมที่ให้ไว้
แก้ไข:เพิ่มฟังก์ชั่นแยกต่างหากสำหรับการยกเว้นปุ่มบางอย่างจาก dict
invert
หมายความว่ามีการkeys
โต้แย้งหรือการkeys
โต้แย้งนั้นถูกปฏิเสธ?" พวกเขาจะเห็นด้วยกี่คน?
หากเราต้องการสร้างพจนานุกรมใหม่โดยลบกุญแจที่เลือกเราสามารถใช้ประโยชน์จากความเข้าใจในพจนานุกรม
เช่น:
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}
ตัวเลือกอื่น:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
แต่คุณจะได้รับlist
(งูหลาม 2) หรือ iterator (งูใหญ่ 3) ส่งกลับโดยไม่ filter()
dict
filtered
ในdict
และคุณได้รับกลับพจนานุกรม!
แบบสั้น:
[s.pop(k) for k in list(s.keys()) if k not in keep]
เป็นที่สุดของคำตอบที่แนะนำเพื่อรักษาความกระชับที่เรามีการสร้างวัตถุที่ซ้ำกันไม่ว่าจะเป็นหรือlist
dict
หนึ่งนี้สร้างโยนไปแต่ลบคีย์ในต้นฉบับlist
dict
นี่เป็นอีกวิธีการง่ายๆที่ใช้del
ในหนึ่งซับ:
for key in e_keys: del your_dict[key]
e_keys
เป็นรายการของกุญแจที่จะยกเว้น มันจะอัพเดท dict ของคุณแทนที่จะให้ใหม่
ถ้าคุณต้องการเอาท์พุทดิจิตัลใหม่ให้ทำสำเนาของดิจิตัลก่อนที่จะลบ:
new_dict = your_dict.copy() #Making copy of dict
for key in e_keys: del new_dict[key]
คุณสามารถใช้python-benedict
มันเป็นคลาสย่อย dict
การติดตั้ง: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
เป็นโอเพ่นซอร์สบน GitHub: https://github.com/fabiocaccamo/python-benedict
คำเตือน: ฉันเป็นผู้เขียนของห้องสมุดนี้