问题
I'm trying to find a similar record between two data sets in a dictionary with which to do further comparisons.
I've confirmed with a print statement that it is finding a matching data set (so all of the code before the final if statement is working). However it is not setting the matchingSet2Record
for some reason. This causes the final if statement to always run even though it is finding a match. Declaring the variable as being in the global variable scope does not work. What is causing this to happen? How do I set the first mathingSet2Record
to the discovered record in the for loop?
The only problem I'm having with this code is that even though matchingSet2Record
is set to the found record properly, it still has a value of None
when trying to compare it in the final if statement. The comparison logic is functioning properly.
I have the following function:
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"
Updated code per answers/comments (still exhibiting the same issue)
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" is a dictionary of dictionaries. That portion of the code is working properly. When I print matchingSet2Record within the for loop that set's it to the matching record it shows that the variable was set properly, however when I do it outside of the for loop it shows a value of None. That is the problem that I'm exploring with this code. The problem does not have anything to do with the code that finds a matching record.
回答1:
This is not a final answer but it's just too much to put into a comment.
I tried to reproduce your problem with an actual dict of data
. But your code really works. There needs to either be
- some pecularities of
data
(I've seen strange effects when e.g. iterating twice over an iterable, because the iterable was already "consumed") - or it really does not match, because you have some invisible differences between the two strings in Field1 and Field2.
This works:
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)
It prints Found
Edit:
If you're into learning python then you can write the above shorter like this:
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')
The last line does a generator: (. for . in .)
creates a generator and next()
makes it generate until it finds the first match. If you get a miss, you'll hit the StopIteration
exception.
Or, alternatively, if you're just into finding out if there are overlaps between the Set1 and Set2 you could do:
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')
See this answer to read more about the isdisjoint
part.
回答2:
Don't use the global
keyword here. You actually want to set the local variable matchingSet2Record
, not the global one.
The code you have is actually setting the value of a variable at the global scope, which is in effect leaving the local variable matchingSet2Record
unchanged. This causes the condition of your if statement to always evaluate to True
since the value of matchingSet2Record
was never updated to non-None
.
来源:https://stackoverflow.com/questions/47839582/accessing-a-variable-outside-of-a-for-loop-in-python-if-global-doesnt-work