I am fairly new to Python and I am trying to understand how list comprehension works. I start with a list of nested lists (lis1), make a copy using list comprehension to give lis2 (in the function scan()). I use a for loop on lis2, to change the first item of each nested list. When I finally print the original list (lis1) I find that the changes to lis2 have mapped back onto the original list. How does this work?

lis1 = [[1,2],[3,4],[5,6],[7,8]]

def scan():
  lis2 = [i for i in lis1]  #list comp
  print "lis2 copy:",lis2
  for x in lis2:            #loops across new list to change first item in nested lists
    x[0] = 333              #to new val 333
  print "lis2 changed:",lis2

print
print "original lis1:",lis1
scan()
print "lis1 also changed:",lis1

>>>
original lis1: [[1, 2], [3, 4], [5, 6], [7, 8]]
lis2 copy: [[1, 2], [3, 4], [5, 6], [7, 8]]
lis2 changed: [[333, 2], [333, 4], [333, 6], [333, 8]]
lis1 also changed: [[333, 2], [333, 4], [333, 6], [333, 8]]

You can not make a copy of a nested list that way, you have to use module copy ...
lis2 = copy.deepcopy(lis1)
rather then the list comprehension, since the nested list in i is still passed as a reference.

Not the best example of list comprehension.
Vegaseat pointet out the problem.

More basic off list comprehension.

>>> l = [0 for i in range(10)]
>>> #So what will l print?
>>> l
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> #So to understand this we can write it like this
>>> l = []
>>> for i in range(10):
	l.append(0)
	
>>> l
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

>>> l = []
>>> for i in range(10):
	l.append(i)
	
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> #So how to do this with list comprehension?
>>> l = [i+0 for i in range(10)]
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> #So to think off it like this
>>> #l = [expr for-clause if-clause]
>>> #We try with if-clause to get only even numbers
>>> l = [i+0 for i in range(10) if i%2 == 0]
>>> l
[0, 2, 4, 6, 8]

>>> #If we write this without list comprehension
>>> l = []
>>> for i in range(10):
	if i%2 == 0:
		l.append(i)
		
>>> l
[0, 2, 4, 6, 8]
>>>
#The basic
#list comprehension.
l = [expr for-clause if-clause]

#Without list comprehension.
l = []
for variable in sequence :
    if filter:
        r.append( expr )
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.