Python字典检查是否存在其他键

5 投票
4 回答
4843 浏览
提问于 2025-04-18 04:32

假设我有一个字典,用来描述一个包裹的一些属性:

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

要检查这个包裹的字典是否有效,它必须包含 'from''to' 这两个键,并且可以有任意数量的其他属性,但至少要有一个其他属性。所以这个字典可以有 'item''weight',也可以同时有这两个,但不能什么都没有。其他的属性键可以是任何东西,不仅限于 'item''weight'

我该如何检查这些字典,以确保它们是有效的,也就是说要有 'to''from' 和至少一个其他的键呢?

我能想到的唯一方法是获取 d.keys(),然后去掉 'from''to' 这两个键,最后检查剩下的是否为空。

有没有更好的方法来做到这一点呢?

4 个回答

1

这段话虽然没有直接解决提问者的问题,但我觉得它提供了一种更好的做法。我知道已经有人回答了这个问题,但我刚花了几分钟时间研究了一下最佳实践,想分享一下我的想法。

使用字典时的问题:

  • 字典是基于键值对的。你必须有两种不同类型的键值,因为tofrom是必填的,而itemweight是可选的。
  • 字典应该是没有逻辑的。设置某些要求会违反字典的基本原则,因为字典只是用来存储数据的。要创建一个实例,你需要为字典构建某种逻辑构造器。

那为什么不直接用类呢?我建议的替代方案是:

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被覆盖或删除,同时限制属性的最小和最大值。

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()
1

如果 d.keys() 的长度至少为3,并且它有一个 from 属性和一个 to 属性,那就没问题了。

我对Python的了解不是很深,但我想它大概是这样的:if len(d.keys) > 2 and d['from'] and d['to']

11
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.viewkeysd.keys返回的是类似集合的对象。所以,我们可以使用集合比较运算符。>用来检查左边的集合是否是右边集合的严格超集。为了满足这个条件,左边的集合对象必须同时包含fromto,以及其他一些对象。

引用自set.issuperset文档

set > other

测试这个集合是否是另一个集合的真正超集,也就是说,set >= other and set != other

撰写回答