【问题标题】:Accessing a variable outside of a for loop in Python if global doesn't work?如果全局不起作用,则访问 Python 中 for 循环之外的变量?
【发布时间】:2017-12-15 20:39:51
【问题描述】:

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

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

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

我有以下功能:

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"

每个答案/cmets 更新的代码(仍然显示相同的问题)

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 循环中打印 matchSet2Record 并将其设置为匹配记录时,它显示该变量已正确设置,但是当我在 for 循环之外执行此操作时,它显示的值为 None。这就是我正在用这段代码探索的问题。该问题与找到匹配记录的代码无关。

【问题讨论】:

  • 如果你想让它在函数中的某个点停止,这就是return 语句的用途。
  • 这不是所描述的问题。我希望能够将声明为 None 的 matchingSet2Record 的值更改为在第一个 for..in 循环中找到的记录,以便可以在最后的 if 语句中访问它。
  • 您发布的代码引发了SyntaxError,因为matchingSet2Record 在声明为全局之前已分配,请澄清您的问题,因为我显然不明白您的问题是什么并且您的代码无效.
  • data 的类型是什么?是字典吗?还是它的一部分是可迭代的?
  • data 是字典的字典。这部分代码工作正常。当我在 for 循环中打印 matchingSet2Record 并将其设置为匹配记录时,它表明变量设置正确,但是当我在 for 循环之外执行它时,它显示的值为 None

标签: python scope global


【解决方案1】:

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

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

【讨论】:

  • 谢谢。我已经从代码中删除了全局语句,但仍然有同样的问题。
  • 能否将新代码附加到您的问题中?
  • 完成,再次引用问题。
  • 谢谢。您能否在 matchingSet2Record = set2Record 行之前添加一条打印语句,然后重新运行您的代码并分享打印语句是否调用?
【解决方案2】:

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

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

  • data 的一些特性(例如,在迭代两次迭代时,我看到了奇怪的效果,因为迭代已经“消耗”了)
  • 或者确实不匹配,因为您在 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 异常。

或者,或者,如果您只是想找出 如果 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 部分的更多信息。

【讨论】:

  • 好的,我已经接受了这个问题的答案(仍然想知道为什么我在发布问题之前看到它打印了“无”值)。但是现在看起来 value1 正在正确地遍历列表,但是嵌套 for 循环中的 value1 没有改变值。这是通过在 for 循环之后但在 if 语句之前添加一个 print 语句来确定的。有什么想法可能导致这种情况吗?
  • 你能改写你的问题吗?在嵌套 (=inner) 循环中没有变量 value1 的重新分配,而只是在外部循环中
猜你喜欢
  • 2019-12-06
  • 2017-12-08
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多