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

python字典检查是否存在给定键以外的任何键,python,dictionary,Python,Dictionary,假设我有一个为包指定某些属性的字典: d={'from':'Bob','to':'Joe','item':'book','weight':'3.5磅} 要检查包字典的有效性,它需要有一个'from'和'To'键,以及任意数量的属性,但必须至少有一个属性。因此,一本词典既可以有'item'也可以有'weight',但两者都不能有。属性键可以是任何内容,不限于'item'或'weight' 我如何检查字典以确保它们是有效的,例如使用'to','from',以及至少一个其他键 我能想到的唯一方法是获取

假设我有一个为包指定某些属性的字典:

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

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

我如何检查字典以确保它们是有效的,例如使用
'to'
'from'
,以及至少一个其他键

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

是否有更好的方法来执行此操作?

如果
d.keys()
的长度至少为3,并且具有from和to属性,则您是金色的

我对Python的了解还不是最丰富的,但我想如果len(d.keys)>2和d['from']以及d['to']

must = {"from", "to"}
print len(d) > len(must) and all(key in d for key in must)
# True
此解决方案确保字典中的元素多于
必须
集合中的元素,并且
必须
中的所有元素都将在字典中

此解决方案的优点是易于扩展。如果要确保字典中还存在一个参数,只需将该参数包含在
must
字典中即可。你不必改变逻辑

编辑

除此之外,如果您使用的是Python2.7,您可以像这样更简洁地完成这项工作

print d.viewkeys() > {"from", "to"}
如果您使用的是Python3.x,那么只需将其编写为

print(d.keys() > {"from", "to"})
这种方法之所以有效,是因为,
d.viewkeys
d.keys
返回类似于对象的集合。因此,我们可以使用集合比较运算符
用于检查左侧集合是否是右侧集合的严格超集。因此,为了满足该条件,左侧set like对象应该同时具有
from
to
,以及一些其他对象

引述

设置>其他 测试集合是否是other的正确超集,即,
set>=other和set!=其他


使用以下代码:

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

这并没有解决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
被覆盖/删除,并限制属性集的最小/最大值。

您可以这样尝试-如果len(d.keys())>2和d.keys()中的“from”和“to”):那么我不知道字典是否是这个实例中的理想数据结构。您认为什么是更理想的数据结构?谢谢。也许是一个类,你可以为这些包创建对象。您的构造函数可以强制将
设置为
设置,并要求设置一个附加属性。它是否可能具有
权重
,这不是金色的?我的第二个约束要求同时具有
.d['from']如果属性不存在,则将抛出错误。如果属性抛出错误,则可以通过另一种方式进行检查。但逻辑是正确的。正如我所说,我不是Python专家,但这更多的是关于逻辑。谢谢,但正如我所说的,可选键可以是任何东西,不限于项目或重量。@VaibhavAggarwal请检查更新的答案,这对您来说合适吗。
len(d)>len(must)和must.issubset(d)
为什么不只是
{“from”,“to”}
?避免调用
set
的原因是因为它是
O(n)
,而不是因为它很难看。@Veedrac好吧,这很奇怪。检查更新的答案。这不需要
设置
转换。谢谢,但我觉得这太过分了。谢谢你!嗯,一个有趣的解决方案,谢谢!不幸的是,看看我现在正在使用的代码,实现该类将涉及大量重构。但这似乎是一个合乎逻辑的解决方案。我将研究在将来实施这项计划。再次感谢!因为它继承了dictionary,所以所有dictionary方法都被保留了下来,但我知道重构的痛苦。祝你好运