假设我有一个字典,它指定了包的一些属性:
d = {'from': 'Bob', 'to': 'Joe', 'item': 'book', 'weight': '3.5lbs'}
要检查包字典的有效性,它需要有'from'
和'to'
键以及任意数量的属性,但必须至少有一个属性。因此,字典可以包含'item'
或'weight'
,但两者都不能。属性键可以是任何内容,不限于'item'
或'weight'
。
我如何检查词典以确保它们有效,例如使用'to'
,'from'
和至少一个其他键?
我能想到的唯一方法是获取d.keys()
,删除'from'
和'to'
密钥,并检查其是否为空。
还有更好的方法吗?
答案 0 :(得分:7)
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"})
此hack有效,因为d.viewkeys
和d.keys
返回类似集合的对象。所以,我们可以使用集合比较运算符。 >
用于检查左侧集是否是右侧集的严格超集。因此,为了满足条件,左侧设置类对象应该同时具有from
和to
以及其他一些对象。
设置>其他
测试该集合是否是其他集合的正确超集,即
set >= other and set != other
。
答案 1 :(得分:1)
如果d.keys()
的长度至少为3,而且它有一个from和to属性,那么你就是金色的。
我对Python的了解并不是最好的,但我认为它类似于if len(d.keys) > 2 and d['from'] and d['to']
答案 2 :(得分:1)
使用以下代码:
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()
答案 3 :(得分:1)
这并没有解决OP的问题,但提供了我认为更好的实践解决方案。我意识到已经有了答案,但我只花了几分钟阅读最佳实践并认为我会分享
使用字典的问题:
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
被覆盖/删除,以及限制属性集的最小/最大值。