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: