Câu hỏi Làm thế nào để loại bỏ một khóa từ một từ điển Python?


Khi cố xóa một khóa khỏi từ điển, tôi viết:

if 'key' in myDict:
    del myDict['key']

Có cách nào để làm điều này không?


1051
2018-06-30 20:27


gốc


Kịch bản điểm chuẩn cho các phương pháp khác nhau được đề xuất trong câu trả lời cho câu hỏi này: gist.github.com/zigg/6280653 - zigg


Các câu trả lời:


Sử dụng dict.pop():

my_dict.pop('key', None)

Điều này sẽ trở lại my_dict[key] nếu key tồn tại trong từ điển, và None nếu không thì. Nếu tham số thứ hai không được chỉ định (ví dụ: my_dict.pop('key')) và key không tồn tại, một KeyError được nuôi dưỡng.


1751
2018-06-30 20:29



Đôi khi một lợi thế của việc sử dụng pop() kết thúc del: nó trả về giá trị cho khóa đó. Bằng cách này bạn có thể nhận và xóa một mục từ một dict trong một dòng mã. - kratenko
Trong câu hỏi, nó không bắt buộc phải giữ giá trị. Điều này sẽ chỉ thêm sự phức tạp không cần thiết. Câu trả lời từ @zigg (bên dưới) là tốt hơn nhiều. - Salvatore Cosentino
@SalvatoreCosentino Tôi không thể làm theo lý lẽ của bạn. Mã trong câu trả lời này phức tạp hơn mã trong câu trả lời khác như thế nào? - Sven Marnach
Xin chào @SvenMarnach, đến 1) Câu trả lời dưới đây là thanh lịch hơn trong quan điểm của tôi (ví dụ, xử lý ngoại lệ) 2) sử dụng 'pop' trong hầu hết các ngôn ngữ lập trình (và cấu trúc dữ liệu) được sử dụng khi bạn muốn lưu trữ giá trị đã xóa và câu hỏi chỉ hỏi về việc xóa một khóa. Trả về một giá trị không bao giờ được sử dụng sẽ đơn giản là không hiệu quả. - Salvatore Cosentino
@SalvatoreCosentino Không, bỏ qua giá trị trả về của hàm không phải là không hiệu quả chút nào. Hoàn toàn ngược lại - giải pháp này nhanh hơn nhiều so với try/except giải pháp nếu khóa không tồn tại. Bạn có thể tìm thấy một hoặc khác dễ dàng hơn để đọc, đó là tốt. Cả hai đều là Python thành ngữ, vì vậy hãy chọn bất cứ điều gì bạn thích. Nhưng tuyên bố rằng câu trả lời này phức tạp hơn hoặc không hiệu quả chỉ đơn giản là không có ý nghĩa. - Sven Marnach


Cụ thể để trả lời "có cách nào để làm điều này không?"

if 'key' in myDict: del myDict['key']

... tốt, bạn yêu cầu ;-)

Tuy nhiên, bạn nên xem xét rằng cách xóa đối tượng này khỏi dict Là không phải nguyên tử-có thể là 'key' có thể ở myDict trong thời gian if tuyên bố, nhưng có thể bị xóa trước del được thực thi, trong trường hợp này del sẽ thất bại với một KeyError. Với điều này, nó sẽ an toàn nhất cho cả hai sử dụng dict.pop hoặc một cái gì đó dọc theo dòng

try:
    del myDict['key']
except KeyError:
    pass

mà, tất nhiên, chắc chắn không phải một lót.


262
2018-06-30 20:36



Yeah, pop chắc chắn là ngắn gọn hơn, mặc dù có một lợi thế chính là làm theo cách này: nó ngay lập tức rõ ràng những gì nó đang làm. - zigg
Các try/except tuyên bố là tốn kém hơn. Tăng một ngoại lệ là chậm. - Chris Barker
@ChrisBarker Tôi đã tìm thấy nếu khóa tồn tại, try là nhanh hơn, mặc dù nếu không, try thực sự là một việc tốt chậm hơn. pop khá nhất quán nhưng chậm hơn tất cả trừ try với một khóa không hiện tại. Xem gist.github.com/zigg/6280653. Cuối cùng, nó phụ thuộc vào mức độ thường xuyên bạn mong đợi chìa khóa để thực sự được trong từ điển, và có hay không bạn cần atomicity - và, tất nhiên, có hay không bạn đang tham gia vào tối ưu hóa sớm;) - zigg
Tôi tin rằng giá trị của sự rõ ràng không nên bỏ qua. 1 cho điều này. - Juan Carlos Coto
về chi phí thử / trừ, bạn cũng có thể đi if 'key' in mydict: #then del.... Tôi cần phải rút ra một chìa khóa / val từ một dict để phân tích chính xác, pop không phải là một giải pháp hoàn hảo. - Marc


Tôi mất một thời gian để tìm ra chính xác my_dict.pop("key", None) đang làm. Vì vậy, tôi sẽ thêm điều này làm câu trả lời để tiết kiệm thời gian khác của googling:

pop (khóa [, mặc định])

Nếu khóa nằm trong từ điển, hãy xóa nó và trả về giá trị của nó, nếu không   trở về mặc định. Nếu mặc định không được cung cấp và khóa không nằm trong   từ điển, một KeyError được nâng lên

Tài liệu


115
2018-03-04 16:43



Chỉ cần gõ help (dict.pop) trong trình thông dịch python. - David
help () và dir () có thể là bạn của bạn khi bạn cần biết điều gì đó. - David
hoặc là dict.pop? trong IPython. - Erik Allik
Ngoài ra, câu trả lời được chấp nhận có liên kết đến tài liệu (với một liên kết đến hàm). - Michael


Thời gian của ba giải pháp được mô tả ở trên.

Từ điển nhỏ:

>>> import timeit
>>> timeit.timeit("d={'a':1}; d.pop('a')")
0.23399464370632472
>>> timeit.timeit("d={'a':1}; del d['a']")
0.15225347193388927
>>> timeit.timeit("d={'a':1}; d2 = {key: val for key, val in d.items() if key != 'a'}")
0.5365207354998063

Từ điển lớn hơn:

>>> timeit.timeit("d={nr: nr for nr in range(100)}; d.pop(3)")
5.478138627299643
>>> timeit.timeit("d={nr: nr for nr in range(100)}; del d[3]")
5.362219126590048
>>> timeit.timeit("d={nr: nr for nr in range(100)}; d2 = {key: val for key, val in d.items() if key != 3}")
13.93129749387532

25
2017-12-07 12:19



Thông thường mọi người viết một conclusion thay vì chỉ bán một số điểm chuẩn. - user1767754


Nếu bạn cần xóa nhiều khóa từ một từ điển trong một dòng mã, tôi nghĩ rằng việc sử dụng map () khá ngắn gọn và có thể đọc được Pythonic:

myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}

Và nếu bạn cần nắm bắt lỗi khi bạn bật một giá trị không có trong từ điển, hãy sử dụng lambda bên trong map () như sau:

map(lambda x: myDict.pop(x,None), ['a','c','e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}

Nó hoạt động. Và 'e' không gây ra lỗi, mặc dù myDict không có khóa 'e'.


20
2017-09-16 19:17



Điều này sẽ không hoạt động trong Python 3 vì map và bạn bè bây giờ là lười biếng và trở về vòng lặp. Sử dụng map đối với tác dụng phụ thường được coi là thực hành kém; một tiêu chuẩn for ... in vòng lặp sẽ tốt hơn. Xem Lượt xem và lặp lại thay vì danh sách để biết thêm thông tin. - Greg Krimer
Bất kể hương vị và phong cách thực hành, việc hiểu danh sách sẽ vẫn hoạt động trong Py3 [myDict.pop(i, None) for i in ['a', 'c']], vì chúng cung cấp một giải pháp thay thế chung cho map (và filter). - mike_e


Sử dụng:

>>> if myDict.get(key): myDict.pop(key)

Cách khác:

>>> {k:v for k, v in myDict.items() if k != 'key'}

Bạn có thể xóa theo điều kiện. Không có lỗi nếu key không tồn tại.


14
2017-12-07 05:52



dict.has_key đã được gỡ bỏ trong Python 3, và thay vào đó, bạn nên sử dụng in (key in myDict). Bạn cũng nên làm điều này trong Python 2. - Artyer
Tôi đặc biệt thích cách sử dụng hiểu từ điển - Matthias Herrmann


Sử dụng từ khóa "del":

del dict[key]

5
2018-05-02 10:22



Giải pháp gọn gàng để xóa khóa trong dict - Ajay Kumar