2013-04-14 46 views
13

dict của tôi trông giống nhưpython: cách tốt nhất để kiểm tra nhiều khóa tồn tại trong từ điển là gì?

d = { 
    'name': 'name', 
    'date': 'date', 
    'amount': 'amount', 
    ... 
} 

Tôi muốn thử nghiệm nếu nameamount tồn tại, vì vậy tôi sẽ làm

if not `name` in d and not `amount` in d: 
    raise ValueError # for example 

Giả sử tôi nhận được dữ liệu từ một api và tôi muốn kiểm tra xem 10 của các trường tồn tại trong từ điển hay không.

Đây có phải là cách tốt nhất để tìm kiếm không?

Trả lời

28

Bạn có thể sử dụng nút giao thông set:

if not d.viewkeys() & {'amount', 'name'}: 
    raise ValueError 

Trong Python 3, mà muốn được:

if not d.keys() & {'amount', 'name'}: 
    raise ValueError 

.keys() trả một cái nhìn dict bởi de lỗi. Dictionary view objects như được trả về bởi .viewkeys() (và .keys() trong Python 3) hoạt động như bộ và kiểm tra giao lộ là rất hiệu quả.

Demo bằng Python 2.7:

>>> d = { 
... 'name': 'name', 
... 'date': 'date', 
... 'amount': 'amount', 
... } 
>>> not d.viewkeys() & {'amount', 'name'} 
False 
>>> del d['name'] 
>>> not d.viewkeys() & {'amount', 'name'} 
False 
>>> del d['amount'] 
>>> not d.viewkeys() & {'amount', 'name'} 
True 

Lưu ý rằng đây kiểm tra thật chỉ khi cả phím bị thiếu. Nếu bạn cần thử nghiệm của bạn để vượt qua nếu hoặc là mất tích, sử dụng:

if not d.viewkeys() >= {'amount', 'name'}: 
    raise ValueError 

mà là False chỉ khi cả phím có mặt:

>>> d = { 
... 'name': 'name', 
... 'date': 'date', 
... 'amount': 'amount', 
... } 
>>> not d.viewkeys() >= {'amount', 'name'} 
False 
>>> del d['amount'] 
>>> not d.viewkeys() >= {'amount', 'name'}) 
True 

Đối với một nghiêm ngặt so sánh (cho phép chỉ hai khóa, không hơn, không kém), trong Python 2, so sánh chế độ xem từ điển với một tập hợp:

if d.viewkeys() != {'amount', 'name'}: 
    raise ValueError 

(Vì vậy, trong Python 3 sẽ là if d.keys() != {'amount', 'name'}).

+0

Tôi đang bối rối một chút, làm thế nào tôi có thể kiểm tra nếu '{'số lượng', 'tên'}' cả hai có mặt trong 'd'? – daydreamer

+0

@daydreamer: 'd.viewkeys()> = {'amount', 'name'}' là 'True' nếu cả hai phím đều hiện diện. –

+0

Tôi cần so sánh nghiêm ngặt, vì vậy tôi tin rằng '>>> d.viewkeys() == {'name', 'amount', 'date'} True' là đủ tốt, bạn nghĩ sao? – daydreamer

9
if all(k not in d for k in ('name', 'amount')): 
    raise ValueError 

hoặc

if all(k in d for k in ('name', 'amount')): 
    # do stuff 
+0

dễ dàng hơn để đọc và vượt tương thích với mọi phiên bản python . +1. – darksky

3

Bạn cũng có thể sử dụng thiết lập như:

>>> d = { 
    'name': 'name', 
    'date': 'date', 
    'amount': 'amount', 
} 
>>> test = set(['name','date']) 
>>> test.issubset(set(d.keys())) 
True 
+1

Nếu bạn đang sử dụng phương thức 'set', bạn không cần chuyển đổi đối số thành' set'. vì vậy 'test.issubset (d.keys())' sẽ hoạt động tốt. Bạn có thể đơn giản hóa điều này hơn nữa và làm 'test.issubset (d)' Ngoài ra 'test' <=' d.viewkeys() '(hoặc' d.keys() 'trên Py3k). Tôi sẽ +1 điều này nếu tôi không hết phiếu bầu – jamylak

+0

Có, bạn nói đúng. Cảm ơn lời đề nghị của bạn! – Sheng

0

Tôi thích hình thức này:

>>> d = { 
... 'name': 'name', 
... 'date': 'date', 
... 'amount': 'amount' 
... } 
>>> tests={'name','date'} 
>>> if any(test not in d for test in tests): 
... raise ValueError 
>>> # no error... 

>>> del d['name'] 
>>> if any(test not in d for test in tests): 
... raise ValueError 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
ValueError 

Hoạt động trên Py 2 hoặc Py 3

Các vấn đề liên quan