Tôi đã có một dict
cái có cả đống mục. Tôi chỉ quan tâm đến một vài trong số họ. Có một cách dễ dàng để cắt tỉa tất cả những người khác ra?
Tôi đã có một dict
cái có cả đống mục. Tôi chỉ quan tâm đến một vài trong số họ. Có một cách dễ dàng để cắt tỉa tất cả những người khác ra?
Câu trả lời:
Xây dựng một chế độ mới:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
Sử dụng hiểu từ điển.
Nếu bạn sử dụng phiên bản thiếu chúng (ví dụ Python 2.6 trở về trước), hãy tạo phiên bản đó dict((your_key, old_dict[your_key]) for ...)
. Nó giống nhau, mặc dù xấu hơn.
Lưu ý rằng điều này, không giống như phiên bản của jnnnnn, có hiệu suất ổn định (chỉ phụ thuộc vào số lượng your_keys) cho old_dict
bất kỳ kích thước nào. Cả về tốc độ và bộ nhớ. Vì đây là biểu thức của trình tạo, nó xử lý một mục tại một thời điểm và nó không xem qua tất cả các mục của old_dict.
Loại bỏ mọi thứ tại chỗ:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
old_dict
chỉ ra một lỗi ở nơi khác, và trong trường hợp đó tôi rất thích một lỗi để âm thầm kết quả sai.
Hiểu một cách trang nhã hơn một chút
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems()
thay thế. .items()
tạo một danh sách khác
Đây là một ví dụ trong python 2.6:
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
Phần lọc là if
tuyên bố.
Phương pháp này chậm hơn câu trả lời của delnan nếu bạn chỉ muốn chọn một vài trong số rất nhiều khóa.
if key in ('x','y','z')
tôi đoán.
Bạn có thể làm điều đó với chức năng dự án từ thư viện funcy của tôi :
from funcy import project
small_dict = project(big_dict, keys)
Ngoài ra hãy xem select_keys .
Mã 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
Mã 2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
Mã 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ất cả các hiệu suất mã được đo bằng thời gian sử dụng số = 1000 và được thu thập 1000 lần cho mỗi đoạn mã.
Đối với python 3.6, hiệu suất của ba cách lọc các khóa chính gần như giống nhau. Đối với python 2.7, mã 3 nhanh hơn một chút.
Điều này lambda lót nên làm việc:
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
Đây là một ví dụ:
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}
Đó là một sự hiểu biết danh sách cơ bản lặp đi lặp lại trên các khóa chính của bạn (i in x) và đưa ra một danh sách các cặp tuple (khóa, giá trị) nếu khóa nằm trong danh sách khóa mong muốn của bạn (y). Một dict () bao bọc toàn bộ thứ để xuất ra dưới dạng một đối tượng dict.
set
cho wanted_keys
, nhưng nếu không có vẻ tốt.
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
, nó trả về {'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
như dự định.
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
và kết quả là {}
, mà tôi cho là một lệnh sai.
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
, tôi nhận được: {'0': [1, 3], '2': [1, 4]}
đó là kết quả dự định
Đưa ra từ điển gốc của bạn orig
và tập hợp các mục mà bạn quan tâm keys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
câu trả lời không hay như câu trả lời của delnan, nhưng sẽ hoạt động trong mọi phiên bản Python quan tâm. Tuy nhiên, nó rất mong manh đối với từng yếu tố keys
hiện có trong từ điển gốc của bạn.
Dựa trên câu trả lời được chấp nhận bởi delnan.
Điều gì xảy ra nếu một trong các khóa mong muốn của bạn không có trong old_dict? Giải pháp delnan sẽ đưa ra một ngoại lệ KeyError mà bạn có thể bắt được. Nếu đó không phải là những gì bạn cần có lẽ bạn muốn:
chỉ bao gồm các khóa tồn tại cả trong old_dict và bộ Want_keys của bạn.
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'}
có một giá trị mặc định cho các khóa không được đặt trong 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 ...}
Hàm này sẽ thực hiện thủ thuật:
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}
Giống như phiên bản của delnan, phiên bản này sử dụng khả năng hiểu từ điển và có hiệu suất ổn định cho các từ điển lớn (chỉ phụ thuộc vào số lượng khóa bạn cho phép chứ không phải tổng số khóa trong từ điển).
Và giống như phiên bản của MyGGan, phiên bản này cho phép danh sách các khóa của bạn bao gồm các khóa có thể không tồn tại trong từ điển.
Và như một phần thưởng, đây là nghịch đảo, nơi bạn có thể tạo một từ điển bằng cách loại trừ các khóa nhất định trong bản gốc:
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}
Lưu ý rằng không giống như phiên bản của delnan, thao tác không được thực hiện tại chỗ, do đó hiệu suất có liên quan đến số lượng phím trong từ điển. Tuy nhiên, ưu điểm của việc này là chức năng sẽ không sửa đổi từ điển được cung cấp.
Chỉnh sửa: Đã thêm một chức năng riêng để loại trừ một số khóa nhất định khỏi một lệnh.
invert
nghĩa là keys
tranh luận được giữ hay keys
lập luận bị từ chối?", Bao nhiêu người trong số họ sẽ đồng ý?
Nếu chúng ta muốn tạo một từ điển mới với các phím đã chọn bị loại bỏ, chúng ta có thể sử dụng khả năng hiểu từ điển
Ví dụ:
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}
Một lựa chọn khác:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
Nhưng bạn nhận được list
(Python 2) hoặc iterator (Python 3) được trả về bởi filter()
, không phải a dict
.
filtered
trong dict
và bạn lấy lại từ điển!
Đây là một phương pháp đơn giản khác sử dụng del
trong một lớp lót:
for key in e_keys: del your_dict[key]
e_keys
là danh sách các khóa được loại trừ. Nó sẽ cập nhật dict của bạn thay vì cung cấp cho bạn một cái mới.
Nếu bạn muốn một dict đầu ra mới, sau đó tạo một bản sao của dict trước khi xóa:
new_dict = your_dict.copy() #Making copy of dict
for key in e_keys: del new_dict[key]
Bạn có thể sử dụng python-benedict
, đó là một lớp con dict.
Cài đặt: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
Đó là mã nguồn mở trên GitHub: https://github.com/fabiocaccamo/python-benedict
Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả của thư viện này.