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