Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #109325 > unrolled thread
| Started by | Marcin Rak <mrak@sightlineinnovation.com> |
|---|---|
| First post | 2016-06-01 17:55 -0700 |
| Last post | 2016-06-02 11:02 -0700 |
| Articles | 8 — 5 participants |
Back to article view | Back to comp.lang.python
Beginner Question Marcin Rak <mrak@sightlineinnovation.com> - 2016-06-01 17:55 -0700
Re: Beginner Question boB Stepp <robertvstepp@gmail.com> - 2016-06-01 20:42 -0500
Re: Beginner Question Marcin Rak <mrak@sightlineinnovation.com> - 2016-06-02 06:10 -0700
Re: Beginner Question Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-02 13:53 +1000
Re: Beginner Question Igor Korot <ikorot01@gmail.com> - 2016-06-02 00:21 -0400
Re: Beginner Question Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-06-02 15:20 +1000
Re: Beginner Question Igor Korot <ikorot01@gmail.com> - 2016-06-02 09:38 -0400
Re: Beginner Question sohcahtoa82@gmail.com - 2016-06-02 11:02 -0700
| From | Marcin Rak <mrak@sightlineinnovation.com> |
|---|---|
| Date | 2016-06-01 17:55 -0700 |
| Subject | Beginner Question |
| Message-ID | <ea789a85-a90c-4ff8-ab34-4b6dc1fc6c2f@googlegroups.com> |
Hi to all
I have a beginner question to which I have not found an answer I was able to understand. Could someone explain why the following program:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
gives us the following result:
[1]
[1,2]
[1,2,3]
How can this be, if we never catch the returned L when we call it, and we never pass it on back to f???
Any help is appreciated.
Marcin
[toc] | [next] | [standalone]
| From | boB Stepp <robertvstepp@gmail.com> |
|---|---|
| Date | 2016-06-01 20:42 -0500 |
| Message-ID | <mailman.74.1464831757.1839.python-list@python.org> |
| In reply to | #109325 |
On Wed, Jun 1, 2016 at 7:55 PM, Marcin Rak <mrak@sightlineinnovation.com> wrote: > Hi to all > > I have a beginner question to which I have not found an answer I was able to understand. Could someone explain why the following program: > > def f(a, L=[]): > L.append(a) > return L > > print(f(1)) > print(f(2)) > print(f(3)) > > gives us the following result: > > [1] > [1,2] > [1,2,3] > > How can this be, if we never catch the returned L when we call it, and we never pass it on back to f??? This comes up rather frequently. In fact, if you just copy your function (Which is used in the official Python tutuorial.) and paste it into Google you will get some relevant hits. One such is: https://pythonconquerstheuniverse.wordpress.com/category/python-gotchas/ As the link will explain the behavior you observe is a consequence of two things: When Python assigns the default argument for the empty list and that lists are *mutable*. Enjoy! -- boB
[toc] | [prev] | [next] | [standalone]
| From | Marcin Rak <mrak@sightlineinnovation.com> |
|---|---|
| Date | 2016-06-02 06:10 -0700 |
| Message-ID | <c21138aa-7400-4d4d-90f6-2b834afe9d9d@googlegroups.com> |
| In reply to | #109326 |
That linked help clear up my confusion...yes you really have to know how things work internally to understand why things happen the way they happen. Thanks again to all
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2016-06-02 13:53 +1000 |
| Message-ID | <574fadda$0$22141$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #109325 |
On Thursday 02 June 2016 10:55, Marcin Rak wrote:
> Hi to all
>
> I have a beginner question to which I have not found an answer I was able to
> understand. Could someone explain why the following program:
>
> def f(a, L=[]):
> L.append(a)
> return L
The default value is set once, and once only, so you get the same list each
time, not a new empty list.
Default values in Python are sort of like this:
HIDDEN_DEFAULT_VALUE = [] # initialised once
def f(a, L):
if L is not defined:
L = HIDDEN_DEFAULT_VALUE
L.append(a)
return L
except that HIDDEN_DEFAULT_VALUE is not actually a global variable. Every
function gets its own storage for defaults. The technical term for this is
"early binding of default values".
If you want to get a new, fresh list each time ("late binding of default
values") you should use a sentinel value:
def f(a, L=None):
if L is None:
L = [] # new, fresh list each time
L.append(a)
return L
--
Steve
[toc] | [prev] | [next] | [standalone]
| From | Igor Korot <ikorot01@gmail.com> |
|---|---|
| Date | 2016-06-02 00:21 -0400 |
| Message-ID | <mailman.75.1464841301.1839.python-list@python.org> |
| In reply to | #109325 |
Hi, guys, On Wed, Jun 1, 2016 at 9:42 PM, boB Stepp <robertvstepp@gmail.com> wrote: > On Wed, Jun 1, 2016 at 7:55 PM, Marcin Rak <mrak@sightlineinnovation.com> wrote: >> Hi to all >> >> I have a beginner question to which I have not found an answer I was able to understand. Could someone explain why the following program: >> >> def f(a, L=[]): >> L.append(a) >> return L >> >> print(f(1)) >> print(f(2)) >> print(f(3)) >> >> gives us the following result: >> >> [1] >> [1,2] >> [1,2,3] >> >> How can this be, if we never catch the returned L when we call it, and we never pass it on back to f??? I think the OP question here is: Why it is printing the array? There is no line like: t = f(1) print t So, why the first print does print the list? The return value should be thrown away... Thank you. > > This comes up rather frequently. In fact, if you just copy your > function (Which is used in the official Python tutuorial.) and paste > it into Google you will get some relevant hits. One such is: > > https://pythonconquerstheuniverse.wordpress.com/category/python-gotchas/ > > As the link will explain the behavior you observe is a consequence of > two things: When Python assigns the default argument for the empty > list and that lists are *mutable*. > > Enjoy! > > > -- > boB > -- > https://mail.python.org/mailman/listinfo/python-list
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2016-06-02 15:20 +1000 |
| Message-ID | <574fc214$0$1585$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #109332 |
On Thursday 02 June 2016 14:21, Igor Korot wrote: > Hi, guys, > > On Wed, Jun 1, 2016 at 9:42 PM, boB Stepp <robertvstepp@gmail.com> wrote: >> On Wed, Jun 1, 2016 at 7:55 PM, Marcin Rak <mrak@sightlineinnovation.com> >> wrote: >>> Hi to all >>> >>> I have a beginner question to which I have not found an answer I was able >>> to understand. Could someone explain why the following program: >>> >>> def f(a, L=[]): >>> L.append(a) >>> return L >>> >>> print(f(1)) >>> print(f(2)) >>> print(f(3)) >>> >>> gives us the following result: >>> >>> [1] >>> [1,2] >>> [1,2,3] >>> >>> How can this be, if we never catch the returned L when we call it, and we >>> never pass it on back to f??? > > I think the OP question here is: > > Why it is printing the array? Because he calls the function, then prints the return result. print(f(1)) calls f(1), which returns [1], then prints [1]. Then he calls: print(f(2)) which returns [1, 2] (but he expects [2]), then prints it. And so on. > There is no line like: > > t = f(1) > print t Correct. But there are lines: print(f(1)) print(f(2)) print(f(3)) -- Steve
[toc] | [prev] | [next] | [standalone]
| From | Igor Korot <ikorot01@gmail.com> |
|---|---|
| Date | 2016-06-02 09:38 -0400 |
| Message-ID | <mailman.93.1464874721.1839.python-list@python.org> |
| In reply to | #109333 |
Steven,
On Thu, Jun 2, 2016 at 1:20 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Thursday 02 June 2016 14:21, Igor Korot wrote:
>
>> Hi, guys,
>>
>> On Wed, Jun 1, 2016 at 9:42 PM, boB Stepp <robertvstepp@gmail.com> wrote:
>>> On Wed, Jun 1, 2016 at 7:55 PM, Marcin Rak <mrak@sightlineinnovation.com>
>>> wrote:
>>>> Hi to all
>>>>
>>>> I have a beginner question to which I have not found an answer I was able
>>>> to understand. Could someone explain why the following program:
>>>>
>>>> def f(a, L=[]):
>>>> L.append(a)
>>>> return L
>>>>
>>>> print(f(1))
>>>> print(f(2))
>>>> print(f(3))
>>>>
>>>> gives us the following result:
>>>>
>>>> [1]
>>>> [1,2]
>>>> [1,2,3]
>>>>
>>>> How can this be, if we never catch the returned L when we call it, and we
>>>> never pass it on back to f???
>>
>> I think the OP question here is:
>>
>> Why it is printing the array?
>
> Because he calls the function, then prints the return result.
>
> print(f(1))
>
> calls f(1), which returns [1], then prints [1].
>
> Then he calls:
>
> print(f(2))
>
> which returns [1, 2] (but he expects [2]), then prints it. And so on.
>
>
>> There is no line like:
>>
>> t = f(1)
>> print t
>
> Correct. But there are lines:
>
> print(f(1))
> print(f(2))
> print(f(3))
I think you missed the point.
Compare:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
vs.
def f(a, L=[]):
L.append(a)
return L
t = f(1)
print t
t = f(2)
print t
t = f(3)
print t
For people that comes from C/C++/Java, the first syntax is kind of weird:
you return a value from the function but the caller does not save it anywhere.
Especially since the return is not a basic type and most of them are
not familiar
with scalar vs list context (sorry for the Perl terminology here)
Thank you.
>
>
>
> --
> Steve
>
> --
> https://mail.python.org/mailman/listinfo/python-list
[toc] | [prev] | [next] | [standalone]
| From | sohcahtoa82@gmail.com |
|---|---|
| Date | 2016-06-02 11:02 -0700 |
| Message-ID | <a3166686-72e6-401b-9347-46c8417ba81b@googlegroups.com> |
| In reply to | #109366 |
On Thursday, June 2, 2016 at 6:38:56 AM UTC-7, Igor Korot wrote: > Steven, > > On Thu, Jun 2, 2016 at 1:20 AM, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: > > On Thursday 02 June 2016 14:21, Igor Korot wrote: > > > >> Hi, guys, > >> > >> On Wed, Jun 1, 2016 at 9:42 PM, boB Stepp <robertvstepp@gmail.com> wrote: > >>> On Wed, Jun 1, 2016 at 7:55 PM, Marcin Rak <mrak@sightlineinnovation.com> > >>> wrote: > >>>> Hi to all > >>>> > >>>> I have a beginner question to which I have not found an answer I was able > >>>> to understand. Could someone explain why the following program: > >>>> > >>>> def f(a, L=[]): > >>>> L.append(a) > >>>> return L > >>>> > >>>> print(f(1)) > >>>> print(f(2)) > >>>> print(f(3)) > >>>> > >>>> gives us the following result: > >>>> > >>>> [1] > >>>> [1,2] > >>>> [1,2,3] > >>>> > >>>> How can this be, if we never catch the returned L when we call it, and we > >>>> never pass it on back to f??? > >> > >> I think the OP question here is: > >> > >> Why it is printing the array? > > > > Because he calls the function, then prints the return result. > > > > print(f(1)) > > > > calls f(1), which returns [1], then prints [1]. > > > > Then he calls: > > > > print(f(2)) > > > > which returns [1, 2] (but he expects [2]), then prints it. And so on. > > > > > >> There is no line like: > >> > >> t = f(1) > >> print t > > > > Correct. But there are lines: > > > > print(f(1)) > > print(f(2)) > > print(f(3)) > > I think you missed the point. > > Compare: > > def f(a, L=[]): > L.append(a) > return L > > print(f(1)) > print(f(2)) > print(f(3)) > > vs. > > def f(a, L=[]): > L.append(a) > return L > > t = f(1) > print t > t = f(2) > print t > t = f(3) > print t > > For people that comes from C/C++/Java, the first syntax is kind of weird: > you return a value from the function but the caller does not save it anywhere. > Especially since the return is not a basic type and most of them are > not familiar > with scalar vs list context (sorry for the Perl terminology here) > > Thank you. > > > > > > > > > > -- > > Steve > > > > -- > > https://mail.python.org/mailman/listinfo/python-list I came from C/C++/Java, and the first syntax makes perfect sense to me. You're just taking the result of a function and directly passing it as a parameter to another. There's nothing confusing about that. C/C++/Java let you do it.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web