python:检查字典中存在多个键的最佳方法是什么?

python:检查字典中存在多个键的最佳方法是什么?,python,dictionary,Python,Dictionary,我的字典看起来像 d = { 'name': 'name', 'date': 'date', 'amount': 'amount', ... } 我想测试name和amount是否存在,所以我会这样做 if not `name` in d and not `amount` in d: raise ValueError # for example 假设我从一个api获取数据,我想测试字典中是否存在10个字段 这仍然是最好的寻找方法吗 if all(k not in d fo

我的字典看起来像

d = {
  'name': 'name',
  'date': 'date',
  'amount': 'amount',
  ...
}
我想测试
name
amount
是否存在,所以我会这样做

if not `name` in d and not `amount` in d:
  raise ValueError # for example
假设我从一个api获取数据,我想测试字典中是否存在
10
个字段

这仍然是最好的寻找方法吗

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


您可以使用
设置
交点:

if not d.viewkeys() & {'amount', 'name'}:
    raise ValueError
在Python 3中,这是:

if not d.keys() & {'amount', 'name'}:
    raise ValueError
因为默认情况下,
.keys()
返回dict视图。例如,由
.viewkeys()
(和Python 3中的
.keys()
返回)充当集合,交叉测试非常有效

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
请注意,仅当两个键都丢失时,此测试才为真。如果缺少其中一项,则需要通过测试,请使用:

if not d.viewkeys() >= {'amount', 'name'}:
    raise ValueError
仅当两个键都存在时才为False:

>>> d = {
...   'name': 'name',
...   'date': 'date',
...   'amount': 'amount',
... }
>>> not d.viewkeys() >= {'amount', 'name'}
False
>>> del d['amount']
>>> not d.viewkeys() >= {'amount', 'name'})
True
为了进行严格的比较(只允许两个键,不多也不少),在Python 2中,将dictionary视图与集合进行比较:

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

(因此在Python3中,如果d.keys()!={'amount','name'},这将是

您还可以使用set作为:

>>> d = {
  'name': 'name',
  'date': 'date',
  'amount': 'amount',
}
>>> test = set(['name','date'])
>>> test.issubset(set(d.keys()))
True
我喜欢这个表格:

>>> 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
>d={
…'name':'name',
…“日期”:“日期”,
…“金额”:“金额”
... }
>>>测试={'name','date'}
>>>如果有(测试中的测试不在d中):
...    升值误差
>>>#没有错误。。。
>>>德尔d['name']
>>>如果有(测试中的测试不在d中):
...    升值误差
... 
回溯(最近一次呼叫最后一次):
文件“”,第2行,在
数值误差

在Py 2或Py 3上工作

为了获得最大效率,您希望避免构造不必要的临时
s(所有非比较二进制运算符都需要)。您可以为以下对象执行此操作:

if name not in d and amount not in d:
与:

但这可能是错误的逻辑(在这两种情况下),因为只有当两个键都缺失时,它才会进入
if
主体(并引发异常),如果其中一个键缺失,您可能希望引发异常

对于更可能拒绝
d
的预期逻辑,除非它同时包含两个键,您需要:

if name not in d or amount not in d:
可通过以下方式使用集合操作完成:

首先,您需要预定义(在函数之外以避免重复构造集合):

然后做:

if not d.keys() >= required_keys:

这两种解决方案(
isdisjoint
=
)都避免构建每次测试的临时集合,并且应该尽可能高效地运行(一旦发现一个键丢失,就立即短路,当两个键都存在时,只需要一对
O(1)
查找)。就个人而言,对于两个键,如果name不在d中或amount不在d中,我会坚持使用
,但是如果键的数量增加,当然可以使用set-like操作。

如果使用
set
方法,则不需要将参数转换为
set
。因此
test.issubset(d.keys())
可以正常工作。你可以进一步简化这一点并进行测试。IsubSet(d)
或者
测试
我有点困惑,我如何测试
{amount',name'}
中是否都存在
d
?@daydreamer:
d.viewkeys()={'amount',name'}
足够好了,你觉得怎么样?@daydreamer:那么你就不需要dict视图了;更新了答案以显示如何进行严格的比较。@莫伯格:再次感谢,我不知道为什么我错过了那个重要的细节。更易于阅读,并且与每个python版本都兼容+1.显然已经很晚了,但我假设如果名称不在d中或金额不在d中,您需要的逻辑是:
:raise ValueError
,而不是
)。使用
,仅当两者都缺失时才会引发异常,但如果其中一个缺失,程序逻辑似乎支持引发异常。如果
是正确的,那么有比您现有的更好的解决方案。
if name not in d or amount not in d:
required_keys = frozenset({"amount", "name"})
if not d.keys() >= required_keys: