如果全局不起作用,在 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
部分的更多信息。
我正在尝试在字典中的两个数据集之间找到相似的记录,以便进一步比较。
我已经通过 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
部分的更多信息。