0

I have this loop that does not mention a list, yet after it is done the list is missing one of its items.

print(numlist)
testlist=numlist
print(testlist)

for i in range(5):
    print(numlist)
    list1=[]
    for numbers in testlist:
        list1.append(numbers[i])

    print(str(numlist)+'before')

    for numbers in testlist: #NUMLIST IS LOSING SOMETHING HERE
        if max(list1)>numbers[i]: 
            testlist.remove(numbers)

    print(str(numlist)+'after')

which outputs

[[13, 13, 13, 2, 2], [13, 13, 13, 3, 3]]before
[[13, 13, 13, 3, 3]]after

3 Answers3

3

You are creating a reference to the numlist when you do

testlist=numlist

Hence whatever changes you do to the numlist will be reflected in testlist. Similarly, any changes done to the testlist will be reflected also in numlist. One way to create a copy of the list is to use

testlist = numlist.copy()

This way you clone a list without creating any reference object to the original list.

As Håken Lid and benvc mentioned in the comments, you could also do

testlist = numlist[:]
Sheldore
  • 37,862
  • 7
  • 57
  • 71
2

I suppose that somewhere before the code you posted you have numlist = testlist.
If that's the case, you should use numlist = list(testlist), to create another instance of the same list.

Here is what is happening:

a = [1,2,3,4,5,6,7,8,9]
b = a
print a # OUTPUT: [1,2,3,4,5,6,7,8,9]
b.pop()
print a # OUTPUT: [1,2,3,4,5,6,7,8]

This happens because when you set numlist = testlist, both the variable names reference to the same list.
If you cast it as a new list, you'll duplicate your list in memory, so each variable point to a different list.

this is not a new argument on SO, this QA provides some really interesting answers and explanations on why this happens, which are the solutions, and pro/cons of each solution

Gsk
  • 2,929
  • 5
  • 22
  • 29
  • @buran that's a clear explanation. scroll down to the [assignment](https://nedbatchelder.com/text/names.html#h_assignment) section to a specific insight. – Gsk Dec 20 '18 at 14:25
  • I am not able to change the comment/link, but I added it as it's really good explanation on python names – buran Dec 20 '18 at 14:32
0

It is because you have created a shallow copy of numlist. Both testlist and numlist will have the same address with shallow copy(bitwise copy). When any action is performed on any one of the lists it is reflected to both lists because of the same address. Create a new instance for testlist so that testlist and numlist have different addresses but same data. You can use something like this:

testlist = numlist.copy()