Re: [Tutor] Output reason
On 7/12/19 11:39 AM, Alan Gauld via Tutor wrote: > On 12/07/2019 15:24, Gursimran Maken wrote: > >> Can someone please explain me the reason for below output. > > You've been bitten by one of the most common gotchas in Python :-) > >> def fun(n,li = []): >> a = list(range(5)) >> li.append(a) >> print(li) >> >> fun(4) >> fun(5,[7,8,9]) >> fun(4,[7,8,9]) >> fun(5) # reason for output (why am I getting to values in this output.) > > When you define a default value in Python it creates the default value > at the time you define the function. It then uses that value each time a > default is needed. in the case of a list that means Python creates an > empty list and stores it for use as the default. It may help in seeing why this happens to be aware that a def: statement is an executable statement like any other, which is executed at the time it is reached in the file. Running it generates a function object, a reference to it being attached to the name of the function. Conceptually, def foo(): is like foo = FunctionConstructor() foo ends up referring to an object that is marked as callable so you can then later call it as foo(). So it makes some sense that some things have to happen at object construction time, like setting up the things that are to be used as defaults. > When you first call the function with the default Python adds values to > the defaiult list. > > Second time you call the function using the default Python adds (more) > values to (the same) default list. FWIW, Python does the same no matter the type of the default argument, but it only causes the trap we poor programmers fall into if the type is one that can be modified ("mutable"). If you have fun(n, a=5) or fun(n, s="stringystuff") those are unchangeable and we don't get this little surprise. By the way, checker tools (and IDEs/editors with embedded checking capabilities) will warn about this, which is a hint on using good tools. pylint would tell you this: W0102: Dangerous default value [] as argument (dangerous-default-value) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Output reason
If I remember how that works right, there is a single empty list that is created and used for all the calls that use the default argument, and then your function modifies that empty list so it is no longer empty, and that modified list is used on future calls. (Not good to use a mutable as a default parameter). A better solution would be to make the default something like None, and test if at the beginning of the function li is None, and if so set it to an empty list, and that empty list will be in function scope so it goes away and a new one is created on a new call. > On Jul 12, 2019, at 10:24 AM, Gursimran Maken > wrote: > > Hi, > > Can someone please explain me the reason for below output. > > Program: > def fun(n,li = []): >a = list(range(5)) >li.append(a) >print(li) > > fun(4) > fun(5,[7,8,9]) > fun(4,[7,8,9]) > fun(5) # reason for output (why am I getting to values in this output.) > > Output: > [[0, 1, 2, 3, 4]] > [7, 8, 9, [0, 1, 2, 3, 4]] > [7, 8, 9, [0, 1, 2, 3, 4]] > [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]] > > Thank you, > Gursimran > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Output reason
On 12/07/2019 15:24, Gursimran Maken wrote: > Can someone please explain me the reason for below output. You've been bitten by one of the most common gotchas in Python :-) > def fun(n,li = []): > a = list(range(5)) > li.append(a) > print(li) > > fun(4) > fun(5,[7,8,9]) > fun(4,[7,8,9]) > fun(5) # reason for output (why am I getting to values in this output.) When you define a default value in Python it creates the default value at the time you define the function. It then uses that value each time a default is needed. in the case of a list that means Python creates an empty list and stores it for use as the default. When you first call the function with the default Python adds values to the defaiult list. Second time you call the function using the default Python adds (more) values to (the same) default list. Sometimes that is useful, usually it's not. The normal pattern to get round this is to use a None default and modify the function like so def fun(n,li = None): if not ni: ni = [] # create new list a = list(range(5)) li.append(a) return li # bad practice to mix logic and display... HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Output reason
Hi, Can someone please explain me the reason for below output. Program: def fun(n,li = []): a = list(range(5)) li.append(a) print(li) fun(4) fun(5,[7,8,9]) fun(4,[7,8,9]) fun(5) # reason for output (why am I getting to values in this output.) Output: [[0, 1, 2, 3, 4]] [7, 8, 9, [0, 1, 2, 3, 4]] [7, 8, 9, [0, 1, 2, 3, 4]] [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]] Thank you, Gursimran ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor