Câu trả lời:
Để xóa khóa bất kể nó có trong từ điển hay không, hãy sử dụng dạng hai đối số của 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. 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, a KeyError
được nâng lên.
Để xóa khóa được đảm bảo tồn tại, bạn cũng có thể sử dụng
del my_dict['key']
Điều này sẽ tăng KeyError
nếu khóa không có trong từ điển.
pop()
hơn 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ã.
try
/ except
nếu khóa không tồn tại. Bạn có thể tìm thấy cái này hay cái khác dễ đọc hơn, điều này tốt. Cả hai đều là Python thành ngữ, vì vậy hãy chọn bất cứ thứ 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.
self
, vì vậy sẽ rất ngạc nhiên nếu phương thức này thực hiện.
Cụ thể để trả lời "có một cách làm việc này không?"
if 'key' in my_dict: del my_dict['key']
... tốt, bạn đã hỏi ;-)
Tuy nhiên, bạn nên cân nhắc rằng cách xóa đối tượng này khỏi một đối tượng không phảidict
là nguyên tử có 'key'
thể có my_dict
trong if
câu lệnh, nhưng có thể bị xóa trước khi del
được thực thi, trong trường hợp đó del
sẽ thất bại với a KeyError
. Với điều này, sẽ an toàn nhất khi sử dụngdict.pop
hoặc một cái gì đó dọc theo dòng
try:
del my_dict['key']
except KeyError:
pass
trong đó, tất nhiên, chắc chắn không phải là một lót.
pop
chắc chắn là ngắn gọn hơn, mặc dù có một lợi thế chính khi làm theo cách này: nó ngay lập tức làm rõ những gì nó đang làm.
try/except
tuyên bố là đắt hơn. Tăng một ngoại lệ là chậm.
try
nhanh hơn một chút, mặc dù nếu không, try
thực sự là một thỏa thuận tốt chậm hơn. pop
là khá nhất quán nhưng chậm hơn tất cả nhưng try
với một khóa không có mặt. Xem gist.github.com/zigg/6280653 . Cuối cùng, điều đó phụ thuộc vào mức độ thường xuyên mà bạn mong đợi khóa thực sự có trong từ điển, và liệu bạn có cần nguyên tử hay không và tất nhiên, liệu bạn có tham gia tối ưu hóa sớm hay không;)
if 'key' in mydict: #then del...
. Tôi cần phải rút ra một khóa / val từ một lệnh để phân tích chính xác, pop không phải là một giải pháp hoàn hảo.
Tôi phải mất một thời gian để tìm ra chính xác những gì my_dict.pop("key", None)
đang làm. Vì vậy, tôi sẽ thêm câu hỏi này như một câu trả lời để tiết kiệm thời gian cho người khác:
pop(key[, default])
Nếu khóa có trong từ điển, hãy xóa nó và trả về giá trị của nó, nếu không thì trả về mặc định . Nếu mặc định không được đưa ra và khóa không có trong từ điển, a
KeyError
sẽ được nâng lên.
dict.pop?
trong IPython.
del my_dict[key]
nhanh hơn một chút so my_dict.pop(key)
với xóa khóa khỏi từ điển khi khóa tồn tại
>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"
>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786
Nhưng khi khóa không tồn tại if key in my_dict: del my_dict[key]
thì nhanh hơn một chút my_dict.pop(key, None)
. Cả hai đều nhanh hơn ít nhất ba lần so với del
trong câu lệnh try
/ except
:
>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
... del d['missing key']
... except KeyError:
... pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133
pop
a del
. Tạo từ điển sẽ hoàn toàn lùn xóa những thứ từ nó.
del
và pop
từ bộ thời gian đầu tiên ở trên)
Nếu bạn cần xóa rất nhiều khóa khỏi 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à Pythonic có thể đọc được:
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 bắt lỗi trong đó 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ư thế này:
map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}
hoặc trong python3
, bạn phải sử dụng một danh sách hiểu thay thế:
[myDict.pop(x, None) for x in ['a', 'c', 'e']]
Nó hoạt động. Và 'e' không gây ra lỗi, mặc dù myDict không có khóa 'e'.
map
và bạn bè bây giờ lười biếng và trả về các trình vòng lặp. Sử dụng map
cho các tác dụng phụ thường được coi là thực hành kém; một for ... in
vòng lặp tiêu chuẩn sẽ tốt hơn. Xem Lượt xem và vòng lặp thay vì danh sách để biết thêm thông tin.
[myDict.pop(i, None) for i in ['a', 'c']]
, vì chúng cung cấp một sự thay thế chung cho map
(và filter
).
for ... in
vòng lặp thông thường .
map()
, thường được sử dụng cho các tác dụng phụ của nó. Sự thay thế được đề xuất trong Python là sự hiểu biết danh sách, mà theo tôi vẫn khá dễ đọc và nhẹ về mặt nhận thức như một lớp lót (xem câu hỏi). Chỉ được sử dụng cho các tác dụng phụ của chúng, cả hai cấu trúc thực sự dẫn đến một danh sách vô dụng, có thể không hiệu quả. Kể từ Python3, tôi không biết về một hàm tích hợp có thể lặp lại một cách an toàn và tao nhã thông qua biểu thức trình tạo, mà không có sản phẩm phụ tốn kém, ví dụ loop(d.pop(k) for k in ['a', 'b'])
.
Bạn có thể sử dụng khả năng hiểu từ điển để tạo một từ điển mới với khóa đó đã bị xóa:
>>> my_dict = {k: v for k, v in my_dict.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.
Sử dụng từ khóa "del":
del dict[key]
Chúng ta có thể xóa khóa khỏi từ điển Python bằng một số cách tiếp cận sau.
Sử dụng del
từ khóa; nó gần như giống như cách bạn đã làm -
myDict = {'one': 100, 'two': 200, 'three': 300 }
print(myDict) # {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : del myDict['one']
print(myDict) # {'two': 200, 'three': 300}
Hoặc là
Chúng ta có thể làm như sau:
Nhưng người ta nên nhớ rằng, trong quá trình này thực sự nó sẽ không xóa bất kỳ khóa nào khỏi từ điển thay vì làm cho khóa cụ thể bị loại trừ khỏi từ điển đó. Ngoài ra, tôi quan sát thấy rằng nó trả về một từ điển không được đặt hàng giống như myDict
.
myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}
Nếu chúng ta chạy nó trong shell, nó sẽ thực thi một cái gì đó giống như {'five': 500, 'four': 400, 'three': 300, 'two': 200}
- lưu ý rằng nó không giống như thứ tự myDict
. Một lần nữa nếu chúng ta cố gắng in myDict
, thì chúng ta có thể thấy tất cả các khóa bao gồm cả chúng ta đã loại trừ khỏi từ điển theo phương pháp này. Tuy nhiên, chúng ta có thể tạo một từ điển mới bằng cách gán câu lệnh sau vào một biến:
var = {key:value for key, value in myDict.items() if key != 'one'}
Bây giờ nếu chúng ta cố gắng in nó, thì nó sẽ tuân theo thứ tự cha mẹ:
print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}
Hoặc là
Sử dụng pop()
phương pháp.
myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)
if myDict.get('one') : myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
Sự khác biệt giữa del
và pop
là, bằng cách sử dụng pop()
phương thức, chúng ta thực sự có thể lưu trữ giá trị của khóa nếu cần, như sau:
myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var) # 100
Ngã ba này ý chính để tham khảo trong tương lai, nếu bạn thấy hữu ích này.
if myDict.get('one')
để kiểm tra nếu có chìa khóa! Không thành công nếu myDict ['one'] có giá trị falsey. Ngoài ra, dicts không có một trật tự vốn có, vì vậy không có ý nghĩa gì khi đề cập đến nó.
Bạn có thể sử dụng xử lý ngoại lệ nếu bạn muốn rất dài dòng:
try:
del dict[key]
except KeyError: pass
Tuy nhiên, điều này chậm hơn so với pop()
phương thức, nếu khóa không tồn tại.
my_dict.pop('key', None)
Sẽ không có vấn đề gì đối với một vài chìa khóa, nhưng nếu bạn thực hiện việc này nhiều lần, thì phương pháp sau là cách tốt hơn.
Cách tiếp cận nhanh nhất là đây:
if 'key' in dict:
del myDict['key']
Nhưng phương pháp này là nguy hiểm vì nếu 'key'
được loại bỏ ở giữa hai dòng, a KeyError
sẽ được nâng lên.
Tôi thích phiên bản bất biến
foo = {
1:1,
2:2,
3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
return {
k:v
for k,v in dct.items() if k not in keyIter
}
>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}
Một cách khác là sử dụng vật phẩm () + hiểu chính tả
các mục () kết hợp với hiểu chính tả cũng có thể giúp chúng tôi đạt được nhiệm vụ xóa cặp khóa-giá trị, nhưng, nó có nhược điểm là không phải là một kỹ thuật đọc chính tả. Trên thực tế, một lệnh mới nếu được tạo ngoại trừ khóa chúng tôi không muốn đưa vào.
test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21}
# Printing dictionary before removal
print ("dictionary before performing remove is : " + str(test_dict))
# Using items() + dict comprehension to remove a dict. pair
# removes vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'}
# Printing dictionary after removal
print ("dictionary after remove is : " + str(new_dict))
Đầu ra:
dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}
điều này sẽ thay đổi
my_dict
tại chỗ (có thể thay đổi)
my_dict.pop('key', None)
tạo ra một lệnh mới (bất biến)
dic1 = {
"x":1,
"y": 2,
"z": 3
}
def func1(item):
return item[0]!= "x" and item[0] != "y"
print(
dict(
filter(
lambda item: item[0] != "x" and item[0] != "y",
dic1.items()
)
)
)