Many newbie questions regarding python

Peter Pearson ppearson at nowhere.invalid
Sun Oct 10 14:57:43 EDT 2010


On Sat, 09 Oct 2010 19:30:16 -0700, Ethan Furman <ethan at 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], [], []]

-- 
To email me, substitute nowhere->spamcop, invalid->net.



More information about the Python-list mailing list