为什么比较#1和比较#2的评估结果不同?

list = [{'objItem':{'key':'exists', 'a':'aaa', 'b':'bbb', 'c':'ccc', 'd':'ddd'}}]
valA = "aaa"
valB = "bbb"
valC = "ccc"


#Comaprisson 1
if valC in list[0]['objItem'].itervalues() and valA in list[0]['objItem'].itervalues() and valB in list[0]['objItem'].itervalues():
    print "True #1"
else:
    print "False #1"

#Comparisson 2
values = list[0]['objItem'].itervalues()
if valC in values and valA in values and valB in values:
    print "True #2"
else:
    print "False #2"


结果是:

$python main.py
True #1
False #2


谢谢

最佳答案

Itervalues(在python-reference上看到)提供了一个迭代器,而不是映射值的列表。
如果使用python 3,则通过values()获取值集合的正确方法。ref
对于python 2,
正确的方法是按照此示例将其作为list(list [0] ['objItem']。itervalues())。

关于两者为何返回不同结果的原因:
正如前面提到的用户0TTT0,
使用values方法时,迭代器将耗尽其值。
但是如果你尝试过


  valC在列表[0] ['objItem']。itervalues()中


再次在您的代码段后,它将返回true。
这是因为list [0] ['objItem']。itervalues()每次都会返回一个新的迭代器对象。但是,另一方面,值具有存储的迭代器对象。
因此:值中的valC将在值运算符中消耗“ ccc”,但list [0] ['objItem']。itervalues()中的valC每次都会消耗一个新的迭代器“ ccc”!

附带说明:
我建议使用反对列表作为变量。
1.因为将变量命名为与对象类型相同是不好的做法。
2.您可以使用更具描述性和复数性的名称

10-07 23:17