Home > Software design >  Add variable to list in for loop
Add variable to list in for loop

Time:02-18

I wrote some Python code to add value to list, but the list didn't update value, so confuse:

lst = []
for i in ["2","3"]: 
    row = []
    row.append(i)
    
    for j in ["2","3"]:  
        row.append(j)
        print("row",row)
        lst.append(row)
        print("lst",lst)
        row.pop(-1)
    row.pop(-1)
            
print("lst",lst)

and here're the result:

lst [[], [], [], []]

the list's element didn't change in for loop and I think the cause's "lst.append(row)" but I don't know how to fix it. The result must be [[2,2],[2,3],[3,2],[3,3]]

CodePudding user response:

You're making a very common mistake for new Python programmers that boils down to this:

lst = []
row = []  # lst and row are empty lists
row.append(1)  # now row is [1]
lst.append(row)  # lst is [[1]]
row.pop(-1)  # row becomes [] again
print(lst)  # surprise! lst is also [[]]

The last line tends to be surprising if you don't realise that adding a list to another list doesn't create a copy of the list, it just assigns the same list to that position of the other list. If you change the inner list through some other variable, that list gets changed, and thus you see that change reflected in the list that contains the list as well.

This would work as expected for your code:

lst = []
for i in ["2","3"]: 
    row = []
    row.append(i)
    
    for j in ["2","3"]:  
        row.append(j)
        print("row",row)
        lst.append(row.copy())  # note the difference here, .copy()
        print("lst",lst)
        row.pop(-1)
    row.pop(-1)
            
print("lst",lst)

It's still a bit overcomplicated, but the problem you had is resolved.

CodePudding user response:

They're empty because you pop everything from them.

Working version:

lst = []
for i in ["2","3"]: 
    for j in ["2","3"]:
        row = []
        row.append(i)
        row.append(j)
        lst.append(row)            
print("lst",lst)

Better version:

lst = []
for i in ["2","3"]: 
    for j in ["2","3"]:
        lst.append([i,j])
print("lst",lst)

List comprehension version:

lst = [[i,j]
       for i in ["2","3"]
       for j in ["2","3"]]
print("lst",lst)

CodePudding user response:

from itertools import product

list(product([2,3], repeat=2))

CodePudding user response:

row is an object inside lst. When you update row with row.pop(), you're removing your items from the row.

>>> lst = []
>>> n=0
>>> for i in ["2","3"]:
...     print("\n Running loop:%d"%(n))
...     print("1",lst)
...     row = [] #<- Your redefining row here, the old connection is gone
...     print("2",lst)
...     row.append(i)
...     for j in ["2","3"]:
...         row.append(j) #
...         lst.append(row) #<- you're duplicating the row here on the second pass through the "j" loop, so now you have the same object twice in lst
...         print("2.1",lst)
...         x=row.pop(-1) #<- you're removing the value from row that you just added...
...         print("2.2",lst)
...     x=row.pop(-1)  #<-  You have one value on row, and you're removing that one here
...     print("3",lst)
...     n =1
...
...

 Running loop:0
1 []
2 []
2.1 [['2', '2']]
2.2 [['2']]
2.1 [['2', '3'], ['2', '3']]
2.2 [['2'], ['2']]
3 [[], []]

 Running loop:1
1 [[], []]
2 [[], []]
2.1 [[], [], ['3', '2']]
2.2 [[], [], ['3']]
2.1 [[], [], ['3', '3'], ['3', '3']]
2.2 [[], [], ['3'], ['3']]
3 [[], [], [], []]
>>>
>>> print("lst",lst)
lst [[], [], [], []]

You can insert your list on the fly like this, no need to make an intermediate.

>>> lst = []
>>> for i in ["2","3"]:
...     for j in ["2","3"]:
...         lst.append([i,j])
...
>>>
>>> print("lst",last)
lst [['2', '2'], ['2', '3'], ['3', '2'], ['3', '3']]
  • Related