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,

<snip>

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:

<snip>

My question is more along the lines of: a mutable object was passed in to func()... what style of loop could be used to turn that one object into /n/ distinct objects? A list comp won't do it, but neither will a for loop, nor a while loop.

Further, Steven stated "it will suffer the exact same surprising behaviour if f modifies the items in place" -- the damage has already been done by that point, as L has however many copies of the *same* object.

Seems to me you would have to use copy.copy or copy.deepcopy to be safe in such a circumstance, and the loop style is irrelevant.

If I've missed something, somebody please enlighten me.

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to