Home > other >  Trying to figure out why this loop prints the wrong list item
Trying to figure out why this loop prints the wrong list item

Time:03-12

With these loops, I'm comparing if a value from dictList1 is in a range value in dictList2. If it is, then I grab the "sample" value from dictList2 and put it in dictList1. However, in my last if statement I'm attempting to handle a scenario where a value from dictList1 is not in dictList2 and then print that value out etc., but what is happening is that it ends up printing the item in the list that is after the item that contains the value that is not in dictList2 - aka it's printing the wrong item in dictList1. I have no idea why

dictList1 = [
    {
        "name" : "item0",
        "num" : 40,
        },
    {
        "name" : "item1",
        "num" : 20,
    },
]

dictList2 = [{'range':range(1,10),'sample':10},{'range':range(11,25),'sample':20},{'range':range(21,30),'sample':30}]

def func():
    for item in dictList1:
        for item2 in dictList2:
            if item['num'] in item2['range']:
                item['sample'] = item2['sample']
    if item['num'] not in item2['range']:
        print(str(item['num'])   " is not in a range.")
    print(dictList1)

func()

CodePudding user response:

for item in dictList1:
    item['num'] = otherFunc(item['query'])
# ... other code

When that loop finishes, item ends up as the final value in dictList1. So all the subsequent references to item will use that final value.

Perhaps you meant to indent the other code underneath this loop?

CodePudding user response:

If I understand correctly, you want the final if in your code to print out any num values from the first list of dictionaries that don't get matched by any of the ranges in the second list of dictionaries. Your current code isn't doing that because when it runs, it's checking only the last value from each list against each other (even if the num matched somewhere else).

Here's what I think you want:

for item in dictList1:
    unmatched = True
    for item2 in dictList2:
        if item['num'] in item2['range']:
            item['sample'] = item2['sample']
            unmatched = False
    if unmatched:
        print(str(item['num'])   " is not in a range.")
print(dictList1)

This code uses a boolean flag variable unmatched to tell the if at the end if a match was found in the inner loop or not. If you only wanted to find one match (e.g. because the ranges in dictList2 never overlapped), you could use slightly simpler code using break and an else clause attached to the loop, like this:

for item in dictList1:
    for item2 in dictList2:
        if item['num'] in item2['range']:
            item['sample'] = item2['sample']
            break
    else:
        print(str(item['num'])   " is not in a range.")
print(dictList1)

This probably won't do what you want though, since you've got overlapping ranges and it will stop the inner loop after the first match is found. The printing logic will be fine, but the in-place modifications to dictList1 will not be the same.

  • Related