Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Many newbie questions regarding python

Reply
Thread Tools

Many newbie questions regarding python

 
 
Ethan Furman
Guest
Posts: n/a
 
      10-10-2010
Steven D'Aprano wrote:
> And how often do you have an list that you are creating where you don't
> know what items you have to initialise the list with?


[snip]

> You are right to point out that the third case is a Python gotcha: [[]]*n
> doesn't behave as expected by the naive or inexperienced Python
> programmer. I should have mentioned it, and pointed out that in that case
> you do want a list comp [[] for i in range(n)].
>
> 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?

~Ethan~
 
Reply With Quote
 
 
 
 
Peter Pearson
Guest
Posts: n/a
 
      10-10-2010
On Sat, 09 Oct 2010 19:30:16 -0700, Ethan Furman <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
 
Ethan Furman
Guest
Posts: n/a
 
      10-11-2010
Peter Pearson wrote:
> On Sat, 09 Oct 2010 19:30:16 -0700, Ethan Furman <(E-Mail Removed)> 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~
 
Reply With Quote
 
Jean-Michel Pichavant
Guest
Posts: n/a
 
      10-11-2010
Peter Pearson wrote:
> On Sat, 09 Oct 2010 19:30:16 -0700, Ethan Furman <(E-Mail Removed)> 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 ...

JM
 
Reply With Quote
 
Peter Pearson
Guest
Posts: n/a
 
      10-11-2010
On Sun, 10 Oct 2010 18:36:27 -0700, Ethan Furman <(E-Mail Removed)> wrote:
[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.


Ah. Quite right. So, Yes, what you want is more objects that
in some sense are copies of the original object. This is getting
way over my head, because there are situations in which it's
hard to say what would constitute a copy of an object, such as
when the object in question is a chat session with a specific
interlocutor.

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

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Questions from a newbie regarding persistant viruses George Orwell Computer Security 0 01-20-2009 01:50 PM
Newbie questions regarding WebSphere and Eclipse Default User Java 0 10-20-2005 08:14 PM
Questions on Canon 300D and etc. questions regarding digital photography Progressiveabsolution Digital Photography 12 03-24-2005 05:18 PM
Newbie questions - Couple of VC++ questions regarding dlls and VB6 Ali Syed C Programming 3 10-13-2004 10:15 PM
How many questions (avg) and How many can i miss? Josh MCSD 2 02-16-2004 07:25 AM



Advertisments