2012-01-24 34 views
72

tôi biết để xóa một mục, 'chìa khóa' từ điển của tôi d, an toàn, bạn cần làm:Loại bỏ nhiều phím từ một cuốn từ điển một cách an toàn

if d.has_key('key'): 
    del d['key'] 

Tuy nhiên, tôi cần phải loại bỏ nhiều mục từ điển một cách an toàn. Tôi đã suy nghĩ của việc xác định các mục trong một tuple như tôi sẽ cần phải làm điều này nhiều hơn một lần.

entitiesToREmove = ('a', 'b', 'c') 
for x in entitiesToRemove: 
    if d.has_key(x): 
     del d[x] 

Tuy nhiên, tôi đã tự hỏi liệu có cách nào thông minh hơn để thực hiện việc này không?

+2

Retrieval thời gian từ một cuốn từ điển là gần O (1) vì băm. Trừ khi bạn đang loại bỏ một tỷ lệ đáng kể các mục, tôi không nghĩ rằng bạn sẽ làm tốt hơn nhiều. – ncmathsadist

+1

Câu trả lời của @mattbornski có vẻ kinh điển hơn, và cũng thành công. –

+0

StackOverflow đã nói: 'khóa trong d' là Pythonic hơn' d.has_key (khóa) 'https://stackoverflow.com/questions/1323410/has-key-or-in –

Trả lời

30

Tại sao không như thế này:

entries = ('a', 'b', 'c') 
the_dict = {'b': 'foo'} 

def entries_to_remove(entries, the_dict): 
    for key in entries: 
     if key in the_dict: 
      del the_dict[key] 

Một phiên bản nhỏ gọn hơn được cung cấp bởi mattbornski sử dụng dict.pop()

2

Tại sao không:

entriestoremove = (2,5,1) 
for e in entriestoremove: 
    if d.has_key(e): 
     del d[e] 

Tôi không biết những gì bạn có ý nghĩa bởi "cách thông minh hơn". Chắc chắn có những cách khác, có lẽ với comprehensions từ điển:

entriestoremove = (2,5,1) 
newdict = {x for x in d if x not in entriestoremove} 
136
d = {'some':'data'} 
entriesToRemove = ('any', 'iterable') 
for k in entriesToRemove: 
    d.pop(k, None) 
+11

** This. ** Đây là sự lựa chọn thông minh của Pythonista. 'dict.pop()' loại bỏ nhu cầu kiểm tra sự tồn tại của khóa. _Excellent._ –

56

Sử dụng Dict Sự hiểu biết

final_dict = {key: t[key] for key in t if key not in [key1, key2]} 

trong đó phím1key2 sẽ bị xóa.

Trong ví dụ bên dưới, các phím "b" và "c" sẽ bị xóa & nó được lưu trong danh sách khóa.

>>> a 
{'a': 1, 'c': 3, 'b': 2, 'd': 4} 
>>> keys = ["b", "c"] 
>>> print {key: a[key] for key in a if key not in keys} 
{'a': 1, 'd': 4} 
>>> 
+1

từ điển mới? danh sách hiểu? Bạn nên điều chỉnh câu trả lời cho người hỏi câu hỏi;) – Glaslos

+0

nó tạo ra một từ điển mới nhưng nó là một lớp lót, vì vậy tôi đã đề cập đến nó. –

+2

Giải pháp này có tác động nghiêm trọng khi biến giữ việc sử dụng tiếp tục trong chương trình. Nói cách khác, một dict từ đó các phím đã bị xóa là hiệu quả hơn nhiều so với một dict mới được tạo ra với các mục được giữ lại. – Apalala

15

Nếu bạn cũng cần thiết để lấy các giá trị cho các phím bạn đang loại bỏ, điều này sẽ là một cách khá tốt để làm điều đó:

valuesRemoved = [d.pop(k, None) for k in entitiesToRemove] 

Bạn có thể dĩ nhiên vẫn làm điều này chỉ dành riêng cho các loại bỏ các phím từ d, nhưng bạn sẽ không nhất thiết phải tạo danh sách các giá trị với danh sách hiểu. Nó cũng là một chút không rõ ràng để sử dụng một danh sách hiểu chỉ dành cho tác dụng phụ của chức năng.

+2

Hoặc nếu bạn muốn giữ các mục đã xóa * làm từ điển: * 'valuesRemoved = dict ((k, d.pop (k, None)) cho k trong entityToRemove)' và cứ thế. – kindall

+0

Bạn có thể bỏ đi việc gán cho một biến. Theo cách này hay cách khác, đó là giải pháp ngắn nhất và đa sắc nhất và nên được đánh dấu là câu trả lời coroh của IMHO. –

12

một giải pháp là sử dụng mapfilter chức năng

python 2

d={"a":1,"b":2,"c":3} 
l=("a","b","d") 
map(d.__delitem__, filter(d.__contains__,l)) 
print(d) 

python 3

d={"a":1,"b":2,"c":3} 
l=("a","b","d") 
list(map(d.__delitem__, filter(d.__contains__,l))) 
print(d) 

bạn nhận được:

{'c': 3} 
+0

Điều này không hiệu quả đối với tôi với python 3.4: '>>> d = {" a ": 1," b ": 2," c ": 3} >>> l = (" a "," b "," d ") >>> bản đồ (d .__ delitem__, bộ lọc (d.__contains __, l)) <đối tượng bản đồ tại 0x10579b9e8> >>> in (d) {'a': 1, 'b': 2, 'c': 3} ' – Risadinha

+0

@Risadinha 'danh sách (bản đồ (d .__ delitem __, bộ lọc (d .__ chứa __, l))) '.... trong python 3.4 map function trả về một iterator –

+2

hoặc' deque (map (...), maxlen = 0) 'để tránh tạo danh sách None giá trị; lần nhập đầu tiên với 'from collections import deque' – Jason

3

Tôi không có vấn đề với bất kỳ câu trả lời đã có, nhưng tôi rất ngạc nhiên khi không tìm thấy giải pháp này:

keys_to_remove = ['a', 'b', 'c'] 
my_dict = {k: v for k, v in zip("a b c d e f g".split(' '), [0, 1, 2, 3, 4, 5, 6])} 

for k in keys_to_remove: 
    try: 
     del my_dict[k] 
    except KeyError: 
     pass 

assert my_dict == {'d': 3, 'e': 4, 'f': 5, 'g': 6} 

Lưu ý: Tôi tình cờ câu hỏi này đến từ here. Và câu trả lời của tôi liên quan đến this answer.

1

inline

import functools 

#: not key(c) in d 
d = {"a": "avalue", "b": "bvalue", "d": "dvalue"} 

entitiesToREmove = ('a', 'b', 'c') 

#: python2 
map(lambda x: functools.partial(d.pop, x, None)(), entitiesToREmove) 

#: python3 

list(map(lambda x: functools.partial(d.pop, x, None)(), entitiesToREmove)) 

print(d) 
# output: {'d': 'dvalue'} 
Các vấn đề liên quan