Python字典检查是否存在其他键
假设我有一个字典,用来描述一个包裹的一些属性:
d = {'from': 'Bob', 'to': 'Joe', 'item': 'book', 'weight': '3.5lbs'}
要检查这个包裹的字典是否有效,它必须包含 'from'
和 'to'
这两个键,并且可以有任意数量的其他属性,但至少要有一个其他属性。所以这个字典可以有 'item'
或 'weight'
,也可以同时有这两个,但不能什么都没有。其他的属性键可以是任何东西,不仅限于 'item'
或 'weight'
。
我该如何检查这些字典,以确保它们是有效的,也就是说要有 'to'
、'from'
和至少一个其他的键呢?
我能想到的唯一方法是获取 d.keys()
,然后去掉 'from'
和 'to'
这两个键,最后检查剩下的是否为空。
有没有更好的方法来做到这一点呢?
4 个回答
这段话虽然没有直接解决提问者的问题,但我觉得它提供了一种更好的做法。我知道已经有人回答了这个问题,但我刚花了几分钟时间研究了一下最佳实践,想分享一下我的想法。
使用字典时的问题:
- 字典是基于键值对的。你必须有两种不同类型的键值,因为
to
和from
是必填的,而item
和weight
是可选的。 - 字典应该是没有逻辑的。设置某些要求会违反字典的基本原则,因为字典只是用来存储数据的。要创建一个实例,你需要为字典构建某种逻辑构造器。
那为什么不直接用类呢?我建议的替代方案是:
class D(dict): # inheirits dict
def __init__ (self,t,f,**attributes): # from is a keyword
self['to'] = t
self['from'] = f
if(len(attributes) > 0):
self.update(attributes)
else:
raise Exception("Require attribute")
d = D('jim','bob',item='book')
print d # {'to': 'jim', 'from': 'bob', 'item': 'book'}
print d['to'] # jim
print d['item'] # item
print d['from'] # bob
d = D('jim','bob') # throws error
显然,如果to
和from
是异步设置的,这个方案就不太适用了,但我认为基本思路还是成立的。创建一个类也能让你更清晰地防止to
和from
被覆盖或删除,同时限制属性的最小和最大值。
请使用下面的代码:
def exists(var, dict):
try:
x = dict[var]
return True
except KeyError:
return False
def check(dict):
if exists('from', dict) == False:
return False
if exists('to', dict) == False:
return False
if exists('item', dict) == False and exists('weight', dict) == False:
return False
return True
def main():
d = {'from': 'Bob', 'to': 'Joe', 'item': 'book', 'weight': '3.5lbs'}
mybool = check(d)
print mybool
if __name__ == '__main__':
main()
如果 d.keys()
的长度至少为3,并且它有一个 from 属性和一个 to 属性,那就没问题了。
我对Python的了解不是很深,但我想它大概是这样的:if len(d.keys) > 2 and d['from'] and d['to']
must = {"from", "to"}
print len(d) > len(must) and all(key in d for key in must)
# True
这个解决方案确保你的字典里有比must
集合中的元素更多的元素,并且must
集合中的所有元素都会在字典里。
这个方案的好处是,它很容易扩展。如果你想确保字典里有一个额外的参数,只需把它加到must
字典里就可以了,其他逻辑不需要改动。
编辑
除此之外,如果你使用的是Python 2.7,你可以更简洁地这样写
print d.viewkeys() > {"from", "to"}
如果你使用的是Python 3.x,你可以简单地写成这样
print(d.keys() > {"from", "to"})
这个技巧之所以有效,是因为d.viewkeys
和d.keys
返回的是类似集合的对象。所以,我们可以使用集合比较运算符。>
用来检查左边的集合是否是右边集合的严格超集。为了满足这个条件,左边的集合对象必须同时包含from
和to
,以及其他一些对象。
引用自set.issuperset
文档,
set > other
测试这个集合是否是另一个集合的真正超集,也就是说,
set >= other and set != other
。