python字典检查是否存在除给定键之外的任何键

时间:2014-04-28 05:20:56

标签: python dictionary

假设我有一个字典,它指定了包的一些属性:

d = {'from': 'Bob', 'to': 'Joe', 'item': 'book', 'weight': '3.5lbs'}

要检查包字典的有效性,它需要有'from''to'键以及任意数量的属性,但必须至少有一个属性。因此,字典可以包含'item''weight',但两者都不能。属性键可以是任何内容,不限于'item''weight'

我如何检查词典以确保它们有效,例如使用'to''from'和至少一个其他键?

我能想到的唯一方法是获取d.keys(),删除'from''to'密钥,并检查其是否为空。

还有更好的方法吗?

4 个答案:

答案 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.viewkeysd.keys返回类似集合的对象。所以,我们可以使用集合比较运算符。 >用于检查左侧集是否是右侧集的严格超集。因此,为了满足条件,左侧设置类对象应该同时具有fromto以及其他一些对象。

引自set.issuperset docs

  

设置>其他

     

测试该集合是否是其他集合的正确超集,即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的问题,但提供了我认为更好的实践解决方案。我意识到已经有了答案,但我只花了几分钟阅读最佳实践并认为我会分享

使用字典的问题:

  • 字典意味着以关键价值为基础。鉴于tofrom是强制性的,itemweight是可选的
  • ,您固有地拥有2种不同类型的键值
  • 字典意味着没有逻辑。通过设置某些要求,您违反了仅用于保存数据的字典的主体。要创建一个实例,您需要为字典构建某种逻辑构造函数

那么为什么不使用一个班级呢?建议的替代方案:

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

如果tofrom被异步设置,显然这会分崩离析,但我认为基本思想仍然存在。创建类还可以防止tofrom被覆盖/删除,以及限制属性集的最小/最大值。