Home > Net >  There is a confusing issue in for loop on Python
There is a confusing issue in for loop on Python

Time:11-03

This code:

user_data_list = [['Full Name', ' Email Address'],['Blossom Gill', ' [email protected]'],
                  ['Hayes Delgado', ' [email protected]'], ['Petra Jones', ' [email protected]'],
                  ['Oleg Noel', ' [email protected]']]
old_domain_email_list = ['[email protected]','[email protected]']
new_domain_email_list = ['[email protected]','[email protected]']
for user in user_data_list[1:]:
    for old_domain, new_domain in zip(old_domain_email_list, new_domain_email_list):
        if user[1] == ' '   old_domain:
            user[1] = ' '   new_domain
print(user_data_list)

The result:

[['Full Name', ' Email Address'], ['Blossom Gill', ' [email protected]'], ['Hayes Delgado', ' [email protected]'], ['Petra Jones', ' [email protected]'], ['Oleg Noel', ' [email protected]']]

I really don't understand why the value of user_data_list list changed in this code. As i can see, just the user variable that was unpacked in the for loop is changed when the if statement is true.

i have tried the same code and i adjust my_list list a bit differently. But the result is different than above code, my_list list did't changed

my_list = ['a','b','c','d']
old_my_list = ['b','d']
new_my_list = ['repalce_1','repalce_2']
for i in my_list:
    for old_, new_ in zip(old_my_list,new_my_list):
        if i == old_:
            i= new_
print(my_list)

The result:

['a', 'b', 'c', 'd']

CodePudding user response:

Though it unpacks, behind the scenes it is referring to the same element hence it is being effected. Look at the memory address it is poiting to the same in the below code.

user_data_list = [['Full Name', ' Email Address'],['Blossom Gill', ' [email protected]'],
                  ['Hayes Delgado', ' [email protected]'], ['Petra Jones', ' [email protected]'],
                  ['Oleg Noel', ' [email protected]']]

print("External id -", id(user_data_list[0]))

for item in user_data_list:
    print("internal for loop id -", id(item))
    break

# Output
# External id          - 2306933340288
# internal for loop id - 2306933340288

CodePudding user response:

In addition to Abhi's answer, you can work around this behaviour by creating a deepcopy of the list. This will have a different memory address

from copy import deepcopy

user_data_list = [['Full Name', ' Email Address'],['Blossom Gill', ' [email protected]'],
                  ['Hayes Delgado', ' [email protected]'], ['Petra Jones', ' [email protected]'],
                  ['Oleg Noel', ' [email protected]']]
original = deepcopy(user_data_list) # 140007211377088 
# OR use the one below.
original = user_data_list[:] # 140007211479424
print(id(user_data_list))
print(id(original))
old_domain_email_list = ['[email protected]','[email protected]']
new_domain_email_list = ['[email protected]','[email protected]']
for user in user_data_list[1:]:
    for old_domain, new_domain in zip(old_domain_email_list, new_domain_email_list):
        if user[1] == ' '   old_domain:
            user[1] = ' '   new_domain
  • Related