Many newbie questions regarding python

Jean-Michel Pichavant jeanmichel at sequans.com
Mon Oct 11 13:49:09 CEST 2010


Peter Pearson wrote:
> 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], [], []]
>
>   
After that many replies and dozen of solutions I wonder if the OP is 
puzzeled or satisfied. Just saying ... :D

JM



More information about the Python-list mailing list