Peter Pearson wrote:
On Sat, 09 Oct 2010 19:30:16 -0700, Ethan Furman <et...@stoneleaf.us> wrote:
Steven D'Aprano wrote:
[snip]
But that doesn't mean that the list comp is the general purpose solution. Consider the obvious use of the idiom:

def func(arg, count):
    # Initialise the list.
    L = [arg for i in range(count)]
    # Do something with it.
    process(L, some_function)

def process(L, f):
    # Do something with each element.
    for item in enumerate(L):
        f(item)

Looks good, right? But it isn't, because it will suffer the exact same surprising behaviour if f modifies the items in place. Using a list comp doesn't save you if you don't know what the object is.
I've only been using Python for a couple years on a part-time basis, so I am not aquainted with this obvious use -- could you give a more concrete example? Also, I do not see what the list comp has to do with the problem in process() -- the list has already been created at that point, so how is it the list comp's fault?

Well, here's a worked example of Steven D's code (Python 2.5.2):

def func(arg, count):
...   L = [arg for i in range(count)]
...   process(L, some_function)
...
def process(L, v):
...   for item in L:
...     v(item)
...
def some_function(x):
...   x.append(1)
...   print x
...
func([], 3)
[1]
[1, 1]
[1, 1, 1]
Is that the output you expected?  Probably not:  the unwary
reader (including me, not too long ago) expects that

  L = [arg for i in range(count)]

will be equivalent to

  L = [[], [], []]

but it's not, because the three elements in the first L are three
references to the *same* list.  Observe:

arg = []
L = [arg for i in range(3)]
L
[[], [], []]
L[0].append(1)
L
[[1], [1], [1]]

... as opposed to ...

L = [ [] for i in range(3)]
L
[[], [], []]
L[0].append(1)
L
[[1], [], []]

After that many replies and dozen of solutions I wonder if the OP is puzzeled or satisfied. Just saying ... :D

JM
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to