我的字典看起来像
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
字典中是否存在字段。
它仍然是寻找的最佳方式吗?
我的字典看起来像
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
字典中是否存在字段。
它仍然是寻找的最佳方式吗?
您可以使用set
交叉点:
if not d.viewkeys() & {'amount', 'name'}:
raise ValueError
在 Python 3 中,这将是:
if not d.keys() & {'amount', 'name'}:
raise ValueError
因为.keys()
默认返回一个字典视图。字典视图对象(例如由.viewkeys()
(和.keys()
在 Python 3 中)返回的)充当集合,并且交集测试非常有效。
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
请注意,仅当两个键都丢失时才测试 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 中,将字典视图与集合进行比较:
if d.viewkeys() != {'amount', 'name'}:
raise ValueError
(所以在 Python 3 中就是这样if d.keys() != {'amount', 'name'}
)。
if all(k not in d for k in ('name', 'amount')):
raise ValueError
或者
if all(k in d for k in ('name', 'amount')):
# do stuff
您也可以使用 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
适用于 Py 2 或 Py 3
为了获得最大效率,您希望避免构造不必要的临时set
s(所有非比较二元运算符都需要)。您可以这样做:
if name not in d and amount not in d:
和:
if d.keys().isdisjoint(("amount", "name")):
但这可能是错误的逻辑(在这两种情况下),因为它仅在两个if
键都丢失时才进入正文(并引发异常) ,并且如果其中一个键丢失,您可能希望引发异常。
对于更可能的拒绝逻辑,d
除非它包含两个键,否则您需要这样:
if name not in d or amount not in d:
这可以通过这种方式通过集合操作来完成:
首先,您需要预先定义(在函数之外避免重复构建集合):
required_keys = frozenset({"amount", "name"})
然后做:
if not d.keys() >= required_keys:
两种解决方案 (isdisjoint
和>=
) 都避免构建每个测试临时集,并且应该尽可能高效地运行(一旦发现缺少单个键就短路,并且只需要O(1)
在两个键都存在时进行查找)。就个人而言,对于只有两个键,我会坚持使用if name not in d or amount not in d:
,但如果键的数量增加,当然可以使用类似集合的操作。