如果全局不起作用,在 Python 中的 for 循环之外访问变量?

Accessing a variable outside of a for loop in Python if global doesn't work?

我正在尝试在字典中的两个数据集之间找到相似的记录,以便进一步比较。

我已经通过 print 语句确认它正在查找匹配的数据集(因此最终 if 语句之前的所有代码都在工作)。但是由于某种原因它没有设置 matchingSet2Record 。这会导致最终的 if 语句始终为 运行,即使它正在寻找匹配项。将变量声明为在全局变量范围内不起作用。是什么导致这种情况发生?如何将第一个 mathingSet2Record 设置为 for 循环中发现的记录?

我在使用这段代码时遇到的唯一问题是,即使 matchingSet2Record 已正确设置为找到的记录,但在尝试时它的值仍然为 None在最后的 if 语句中比较它。比较逻辑运行正常。

我有以下功能:

def processFile(data):
    # Go through every Record
    for set1Record in data["Set1"]:
        value1 = set1Record["Field1"].strip()
        matchingSet2Record = None

        # Find the EnergyIP record with the meter number
        for set2Record in data["Set2"]:
            if set2Record["Field2"].strip() == value1:
                global matchingSet2Record 
                matchingSet2Record = set2Record 

        # If there was no matching Set2 record, report it
        if matchingSet2Record == None:
            print "Missing"

根据 answers/comments 更新了代码(仍然存在相同的问题)

def processFile(data):
    # Go through every Record
    for set1Record in data["Set1"]:
        value1 = set1Record["Field1"].strip()
        matchingSet2Record = None

        # Find the EnergyIP record with the meter number
        for set2Record in data["Set2"]:
            if set2Record["Field2"].strip() == value1:
                matchingSet2Record = set2Record 

        # If there was no matching Set2 record, report it
        if matchingSet2Record == None:
            print "Missing"

"data" 是字典中的字典。该部分代码工作正常。当我在将它设置为匹配记录的 for 循环中打印 matchingSet2Record 时,它显示变量设置正确,但是当我在 for 循环之外执行它时,它显示值 None。这就是我用这段代码探索的问题。该问题与查找匹配记录的代码没有任何关系。

不要在此处使用 global 关键字。您实际上想设置局部变量 matchingSet2Record,而不是全局变量。

您的代码实际上是在全局范围内设置变量的值,这实际上使局部变量 matchingSet2Record 保持不变。这会导致您的 if 语句的条件始终评估为 True,因为 matchingSet2Record 的值从未更新为非 None.

这不是最终答案,但评论太多了。

我试图用 data 的实际字典重现您的问题。但是您的代码确实有效。需要有

  • data 的一些特点(例如,在可迭代对象上迭代两次时,我看到了奇怪的效果,因为可迭代对象已经 "consumed")
  • 或者真的不匹配,因为你在 Field1 和 Field2 中的两个字符串之间存在一些不可见的差异。

有效:

def processFile(data):
    # Go through every Record
    for set1Record in data["Set1"]:
        value1 = set1Record["Field1"].strip()
        matchingSet2Record = None

        # Find the EnergyIP record with the meter number
        for set2Record in data["Set2"]:
            if set2Record["Field2"].strip() == value1:
                matchingSet2Record = set2Record 

        # If there was no matching Set2 record, report it
        if matchingSet2Record == None:
            print("Missing")
        else:
            print("Found")

if __name__ == '__main__':
    data = dict(Set1=[dict(Field1='value1')], Set2=[dict(Field2='value1')])
    processFile(data)

它打印 Found

编辑:

如果你喜欢学习 python 那么你可以将上面的内容写得更短:

data = dict(Set1=[dict(Field1='value1')], Set2=[dict(Field2='value1 ')])
for value1 in [v['Field1'].strip() for v in data['Set1']]:
    try:
        matchingSet2Record = (v for v in data['Set2'] if v['Field2'].strip() == value1).next()
        print("found {}".format(matchingSet2Record))
    except StopIteration:
        print('Missing')

最后一行是一个生成器:(. for . in .) 创建一个生成器,next() 让它生成直到找到第一个匹配项。如果你错过了,你会遇到 StopIteration 异常。

或者,如果您只是想找出 if Set1 和 Set2 之间存在重叠,您可以这样做:

data = dict(Set1=[dict(Field1='value1')], Set2=[dict(Field2='value1')])
field1 = [a['Field1'].strip() for a in data['Set1']]
field2 = [a['Field2'].strip() for a in data['Set2']]
if not set(field1).isdisjoint(field2):
    print('there is at least 1 common element between Set1 and Set2')

请参阅 this answer 以了解有关 isdisjoint 部分的更多信息。