Re: Passing a list into a list .append() method
On Tuesday, September 9, 2014 11:25:29 AM UTC+5:30, JBB wrote: > I have a list with a fixed number of elements which I need to grow; ie. add > rows of a fixed number of elements, some of which will be blank. > e.g. [['a','b','c','d'], ['A','B','C','D'], ['', 'aa', 'inky', ''], ['', > 'bb', 'binky', ''], ... ] > This is a reduced representation of a larger list-of-lists problem that had > me running in circles today. > I think I figured out _how_ to get what I want but I am looking to > understand why one approach works and another doesn't. > 1) What does NOT work as desired: > proc_file = [] > proc_file = [['a','b','c','d']] > proc_file.append(['A','B','C','D']) > blank_r = ['','','',''] > qq = ['aa','bb','cc','dd'] > rr = ['inky', 'binky', 'pinky', 'clyde'] > for i,j in enumerate(zip(qq,rr)): > proc_file.append((blank_r)) # Add a row of blanks > proc_file[i+2][1] = j[0] > proc_file[i+2][2] = j[1] > print len(proc_file), blank_r, proc_file > print > print > proc_file > 3 ['', 'aa', 'inky', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', > 'aa', 'inky', '']] > 4 ['', 'bb', 'binky', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', > 'bb', 'binky', ''], ['', 'bb', 'binky', '']] > 5 ['', 'cc', 'pinky', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', > 'cc', 'pinky', ''], ['', 'cc', 'pinky', ''], ['', 'cc', 'pinky', '']] > 6 ['', 'dd', 'clyde', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', > 'dd', 'clyde', ''], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', ''], ['', > 'dd', 'clyde', '']] > Out[82]: > [['a', 'b', 'c', 'd'], > ['A', 'B', 'C', 'D'], > ['', 'dd', 'clyde', ''], > ['', 'dd', 'clyde', ''], > ['', 'dd', 'clyde', ''], > ['', 'dd', 'clyde', '']] > 2) What works as desired: > proc_file = [] > proc_file = [['a','b','c','d']] > proc_file.append(['A','B','C','D']) > blank_r = ['','','',''] > qq = ['aa','bb','cc','dd'] > rr = ['inky', 'binky', 'pinky', 'clyde'] > for i,j in enumerate(zip(qq,rr)): > proc_file.append(list(blank_r)) # Change it to list(blank_r) and it works > proc_file[i+2][1] = j[0] > proc_file[i+2][2] = j[1] > print len(proc_file), blank_r, proc_file > print > print > proc_file > 3 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', > 'inky', '']] > 4 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', > 'inky', ''], ['', 'bb', 'binky', '']] > 5 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', > 'inky', ''], ['', 'bb', 'binky', ''], ['', 'cc', 'pinky', '']] > 6 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', > 'inky', ''], ['', 'bb', 'binky', ''], ['', 'cc', 'pinky', ''], ['', 'dd', > 'clyde', '']] > Out[83]: > [['a', 'b', 'c', 'd'], > ['A', 'B', 'C', 'D'], > ['', 'aa', 'inky', ''], > ['', 'bb', 'binky', ''], > ['', 'cc', 'pinky', ''], > ['', 'dd', 'clyde', '']] Dont quite know what you are trying to do. Does this serve your purpose? >>> proc_file = [['a','b','c','d']] >>> proc_file.append(['A','B','C','D']) >>> blank_r = ['','','',''] >>> [[i,j0,j1, ""] for (i, (j0, j1)) in enumerate(zip(qq,rr))] [[0, 'aa', 'inky', ''], [1, 'bb', 'binky', ''], [2, 'cc', 'pinky', ''], [3, 'dd', 'clyde', '']] Or if you prefer: >>> proc_file + [[i,j0,j1, ""] for (i, (j0, j1)) in enumerate(zip(qq,rr))] [['a', 'b', 'c', 'd'], [0, 'aa', 'inky', ''], [1, 'bb', 'binky', ''], [2, 'cc', 'pinky', ''], [3, 'dd', 'clyde', '']] -- https://mail.python.org/mailman/listinfo/python-list
Re: Passing a list into a list .append() method
Peter Otten <__peter__ web.de> writes: [Deletia] To Peter Otten and Paul Kroeger: Thank you both, very much. I think I now get why the binding works as it does in addition to why the list() approach worked. (Third attempt - priors not going through, please excuse any repetition) JBB -- https://mail.python.org/mailman/listinfo/python-list
Re: Passing a list into a list .append() method
Paul Kroeger prz-wugen.com> writes: > > Hello, > > I'm myself still learning Python, so others may please correct me, if > I'm wrong. ... > I hope, the above helps to understand why this behaviour.is to be > expected. > To Peter Otten and Paul Kroeger: Thank you both, very much. I think I now get why the binding works as it does in addition to why the list() approach worked. JBB -- https://mail.python.org/mailman/listinfo/python-list
Re: Passing a list into a list .append() method
Hello, I'm myself still learning Python, so others may please correct me, if I'm wrong. Consider the following sentence of your link "jeffknupp.com/...": "some_guy and first_names[0] both refer to the same object" This is what is going on here. Am Dienstag, den 09.09.2014, 05:50 + schrieb JBB: > [...] > > for i,j in enumerate(zip(qq,rr)): > proc_file.append((blank_r)) # Add a row of blanks At this point, the last "row" of "proc_file" and the variable "blank_r" both refer to the list object [blank_r]. > proc_file[i+2][1] = j[0] > proc_file[i+2][2] = j[1] The object under "proc_file[...]" is changed now. This object is the list object [blank_r]! So "proc_file[-1]" and "blank_r" both refer to [blank_r] = ["", j[0], j[1], ""], which is added do the list object [proc_file] at the beginning of the next iteration. Thus, all entries of [proc_file] with index greater 1 are bound to [blank_r], which is itself modified in each iteration to the corresponding j: proc_file[0] -> ["a", "b,", "c", "d"] proc_file[1] -> ["A", "B,", "C", "D"] proc_file[2] -> [blank_r] proc_file[3] -> [blank_r] proc_file[4] -> [blank_r] proc_file[5] -> [blank_r] ... Thus, printing proc_file will always print the values of the last j for all rows greater than 1. Maybe, this will help (although I think you got it already: proc_file = [] proc_file = [['a','b','c','d']] proc_file.append(['A','B','C','D']) blank_r = ['','','',''] qq = ['aa','bb','cc','dd'] rr = ['inky', 'binky', 'pinky', 'clyde'] for i,j in enumerate(zip(qq,rr)): proc_file.append((blank_r)) # Add a row of blanks print "proc_file at loop entry:", proc_file print "current blank_r:", blank_r proc_file[i+2][1] = j[0] proc_file[i+2][2] = j[1] print "proc_file at loop end:", proc_file, "\n\n" And maybe thinking of lists as objects and of variables "containing" lists (somehow) as "pointers" may also help. > [...] 2) What works as desired: > proc_file.append(list(blank_r)) # Change it to list(blank_r) and it works The list() function returns a copy of [blank_r]. So with this code, "proc_file[-1]" refers not the same list object as "blank_r". This leads to the desired behaviour of your program. > It looks like .append binds blank_r to proc_file in 1). I change proc_file > and blank_r changes along with it. Should I expect this? [...] I hope, the above helps to understand why this behaviour.is to be expected. So long, Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Passing a list into a list .append() method
JBB wrote: > I have a list with a fixed number of elements which I need to grow; ie. > add rows of a fixed number of elements, some of which will be blank. > > e.g. [['a','b','c','d'], ['A','B','C','D'], ['', 'aa', 'inky', ''], ['', > 'bb', 'binky', ''], ... ] > > This is a reduced representation of a larger list-of-lists problem that > had me running in circles today. > > I think I figured out _how_ to get what I want but I am looking to > understand why one approach works and another doesn't. The actual problem is that you are appending the same list multiple times. In nuce: >>> inner = [1, 2, 3] >>> outer = [inner, inner, inner] Remember that outer[0] is inner just like the two other items of the outer list: >>> outer[0] is inner True >>> outer[1] is inner True >>> outer[2] is inner True So >>> outer[0][0] = 42 effectively changes inner >>> inner [42, 2, 3] which is reflected in the following output: >>> outer [[42, 2, 3], [42, 2, 3], [42, 2, 3]] With list(inner) you create a (shallow) copy of inner >>> inner = [1, 2, 3] >>> outer = [list(inner), list(inner), list(inner)] >>> outer[0] is inner False and a subsequent assignment changes only that specific copy of inner: >>> outer[0][0] = 42 >>> outer [[42, 2, 3], [1, 2, 3], [1, 2, 3]] So the key to the solution is that you create a new list on every iteration of the loop. With that in mind I'd write for a, b, in zip(qq, rr): proc_file.append(["", a, b, ""]) or alternatively if the actual inner list is more complex template = ["", "", "", ""] for p in zip(qq, rr): inner = list(template) inner[1:3] = p proc_file.append(inner) > 1) What does NOT work as desired: > proc_file.append((blank_r)) # Add a row of blanks > proc_file[i+2][1] = j[0] > proc_file[i+2][2] = j[1] > 2) What works as desired: > proc_file.append(list(blank_r)) # Change it to list(blank_r) and it > works > proc_file[i+2][1] = j[0] > proc_file[i+2][2] = j[1] > print len(proc_file), blank_r, proc_file -- https://mail.python.org/mailman/listinfo/python-list
Re: Passing a list into a list .append() method
Frank Millman chagford.com> writes: > > > "JBB" gmail.com> wrote in message > news:loom.20140909T073428-713 post.gmane.org... > >I have a list with a fixed number of elements which I need to grow; ie. add > > rows of a fixed number of elements, some of which will be blank. ... > I am sure that someone will give you a comprehensive answer, but here is a > quick clue which may be all you need. >... [ Deletia per gmane's requirements ] > Wrapping a list with 'list()' has the effect of making a copy of it. > > This is from the docs (3.4.1) - > > """ > Lists may be constructed in several ways: > > - Using a pair of square brackets to denote the empty list: [] > - Using square brackets, separating items with commas: [a], [a, b, c] > - Using a list comprehension: [x for x in iterable] > - Using the type constructor: list() or list(iterable) > > The constructor builds a list whose items are the same and in the same order > as iterable's items. > iterable may be either a sequence, a container that supports iteration, or > an iterator object. > If iterable is already a list, a copy is made and returned, similar to > iterable[:]. [*] > For example, list('abc') returns ['a', 'b', 'c'] and list( (1, 2, 3) ) > returns [1, 2, 3]. > If no argument is given, the constructor creates a new empty list, []. > """ > > I marked the relevant line with [*] > > HTH > > Frank Millman Ok, this does clear up why the list() construction worked in this context - I wasn't aware that it would create a copy. I'm still a little confused by why passing the list as an argument causes the list to change. But, I was not aware of the id() method to see what's equivalent to what. I'll experiment with this and you've given me some good ideas on other docs I need to read. Thank you for the quick reply. JBB -- https://mail.python.org/mailman/listinfo/python-list
Re: Passing a list into a list .append() method
"JBB" wrote in message news:loom.20140909t073428-...@post.gmane.org... >I have a list with a fixed number of elements which I need to grow; ie. add > rows of a fixed number of elements, some of which will be blank. > > e.g. [['a','b','c','d'], ['A','B','C','D'], ['', 'aa', 'inky', ''], ['', > 'bb', 'binky', ''], ... ] > > This is a reduced representation of a larger list-of-lists problem that > had > me running in circles today. > > I think I figured out _how_ to get what I want but I am looking to > understand why one approach works and another doesn't. > [...] > > Next, I tried passing it as list(tuple(blank_r)) which worked. Then, I > finally settled on 2) where I dispensed with the tuple conversion. > I am sure that someone will give you a comprehensive answer, but here is a quick clue which may be all you need. >>> x = [1, 2, 3] >>> id(x) 16973256 >>> y = x >>> id(y) 16973256 >>> z = list(x) >>> id(z) 17004864 Wrapping a list with 'list()' has the effect of making a copy of it. This is from the docs (3.4.1) - """ Lists may be constructed in several ways: - Using a pair of square brackets to denote the empty list: [] - Using square brackets, separating items with commas: [a], [a, b, c] - Using a list comprehension: [x for x in iterable] - Using the type constructor: list() or list(iterable) The constructor builds a list whose items are the same and in the same order as iterable's items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to iterable[:]. [*] For example, list('abc') returns ['a', 'b', 'c'] and list( (1, 2, 3) ) returns [1, 2, 3]. If no argument is given, the constructor creates a new empty list, []. """ I marked the relevant line with [*] HTH Frank Millman -- https://mail.python.org/mailman/listinfo/python-list
Passing a list into a list .append() method
I have a list with a fixed number of elements which I need to grow; ie. add rows of a fixed number of elements, some of which will be blank. e.g. [['a','b','c','d'], ['A','B','C','D'], ['', 'aa', 'inky', ''], ['', 'bb', 'binky', ''], ... ] This is a reduced representation of a larger list-of-lists problem that had me running in circles today. I think I figured out _how_ to get what I want but I am looking to understand why one approach works and another doesn't. 1) What does NOT work as desired: proc_file = [] proc_file = [['a','b','c','d']] proc_file.append(['A','B','C','D']) blank_r = ['','','',''] qq = ['aa','bb','cc','dd'] rr = ['inky', 'binky', 'pinky', 'clyde'] for i,j in enumerate(zip(qq,rr)): proc_file.append((blank_r)) # Add a row of blanks proc_file[i+2][1] = j[0] proc_file[i+2][2] = j[1] print len(proc_file), blank_r, proc_file print print proc_file 3 ['', 'aa', 'inky', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', 'inky', '']] 4 ['', 'bb', 'binky', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'bb', 'binky', ''], ['', 'bb', 'binky', '']] 5 ['', 'cc', 'pinky', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'cc', 'pinky', ''], ['', 'cc', 'pinky', ''], ['', 'cc', 'pinky', '']] 6 ['', 'dd', 'clyde', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', '']] Out[82]: [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', ''], ['', 'dd', 'clyde', '']] 2) What works as desired: proc_file = [] proc_file = [['a','b','c','d']] proc_file.append(['A','B','C','D']) blank_r = ['','','',''] qq = ['aa','bb','cc','dd'] rr = ['inky', 'binky', 'pinky', 'clyde'] for i,j in enumerate(zip(qq,rr)): proc_file.append(list(blank_r)) # Change it to list(blank_r) and it works proc_file[i+2][1] = j[0] proc_file[i+2][2] = j[1] print len(proc_file), blank_r, proc_file print print proc_file 3 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', 'inky', '']] 4 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', 'inky', ''], ['', 'bb', 'binky', '']] 5 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', 'inky', ''], ['', 'bb', 'binky', ''], ['', 'cc', 'pinky', '']] 6 ['', '', '', ''] [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', 'inky', ''], ['', 'bb', 'binky', ''], ['', 'cc', 'pinky', ''], ['', 'dd', 'clyde', '']] Out[83]: [['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D'], ['', 'aa', 'inky', ''], ['', 'bb', 'binky', ''], ['', 'cc', 'pinky', ''], ['', 'dd', 'clyde', '']] Due diligence I've read extensively on how arguments are passed to functions but I don't think they are completely applicable here (though interesting nevertheless) http://www.jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/ https://www.udacity.com/wiki/common-python-pitfalls and others. It looks like .append binds blank_r to proc_file in 1). I change proc_file and blank_r changes along with it. Should I expect this? I understand lists are mutable but I didn't expect that they could be associated/bound in this manner. I first tried "protecting" blank_r by passing it as a tuple. That caused an expected mismatch error. Next, I tried passing it as list(tuple(blank_r)) which worked. Then, I finally settled on 2) where I dispensed with the tuple conversion. -- https://mail.python.org/mailman/listinfo/python-list
Re: append method
On Wed, May 23, 2012 at 12:42 PM, Dave Angel wrote: > On 05/23/2012 03:13 PM, Emile van Sebille wrote: >> A design decision -- there's currently a mix of methods that return >> themselves and not. Mostly is appears to me that mutables modify in >> place without returning self and immutables return the new value. >> > > It's simpler than that. Methods/functions either modify the object (or > one of their arguments), or return the results, but generally not both. > So sorted() returns a sorted list without modifying the input. And the > sort() method modifies the list, but does not return it. So you're > right that methods on non-mutables must return the new value, since they > can't modify the object. While this is true, its also important to keep in mind that, mostly due to magic methods, what appears to be a single function call my be multiple, and as such there are cases which appear to do both. Consider sorted on a generator. It returns the result, but the magic method __iter__ is implicitly called by sorted, and mutates the generator. Aside from those cases, the only cases I can think of in the Python standard library are cases where the code is only intended to be used directly in the interpreter, and not scripted, namely debugging aids such as pstats, where the convenience of having both outweighs the potential of confusion. -- http://mail.python.org/mailman/listinfo/python-list
Re: append method
On 05/23/2012 03:13 PM, Emile van Sebille wrote: > On 5/23/2012 5:23 AM 水静流深 said... >> >>> s=[1,2,3] >> >>> s.append(5) >> >>> s >> [1, 2, 3, 5] >> >>> s=s.append(5) >> >>> s >> >>> print s >> None >> >> why can't s=s.append(5) > > It could, but it doesn't. > > >> ,what is the reason? > > > A design decision -- there's currently a mix of methods that return > themselves and not. Mostly is appears to me that mutables modify in > place without returning self and immutables return the new value. > > But that's simply my observation. > > Emile > > It's simpler than that. Methods/functions either modify the object (or one of their arguments), or return the results, but generally not both. So sorted() returns a sorted list without modifying the input. And the sort() method modifies the list, but does not return it. So you're right that methods on non-mutables must return the new value, since they can't modify the object. -- DaveA -- http://mail.python.org/mailman/listinfo/python-list
Re: append method
On 5/23/2012 5:23 AM 水静流深 said... >>> s=[1,2,3] >>> s.append(5) >>> s [1, 2, 3, 5] >>> s=s.append(5) >>> s >>> print s None why can't s=s.append(5) It could, but it doesn't. ,what is the reason? A design decision -- there's currently a mix of methods that return themselves and not. Mostly is appears to me that mutables modify in place without returning self and immutables return the new value. But that's simply my observation. Emile -- http://mail.python.org/mailman/listinfo/python-list
Re: append method
On Wed, May 23, 2012 at 8:23 AM, 水静流深 <1248283...@qq.com> wrote: s=[1,2,3] s.append(5) s > [1, 2, 3, 5] s=s.append(5) s print s > None > > why can't s=s.append(5) ,what is the reason? For the same reason that you don't see `[1, 2, 3, 5]` immediately after doing `s.append(5)` the first time around, but must instead check `s`: because the value is not returned from the function. `s` is modified in-place, and nothing is returned. This was a deliberate design decision made a long time ago that is very well documented; try Googling for `python why doesn't list.append return the value` for example. -- ~Zahlman {:> -- http://mail.python.org/mailman/listinfo/python-list
Re: append method
wrote: >>> s=[1,2,3] >>> s.append(5) >>> s [1, 2, 3, 5] >>> s=s.append(5) >>> s >>> print s None why can't s=s.append(5) ,what is the reason? Because the append method returns None, not the object. It modifies the object in place, and does not create any copy. You can still write s = s + [5] if you really want to, but what's the point ? JM -- http://mail.python.org/mailman/listinfo/python-list
append method
>>> s=[1,2,3] >>> s.append(5) >>> s [1, 2, 3, 5] >>> s=s.append(5) >>> s >>> print s None why can't s=s.append(5) ,what is the reason?-- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On 7/13/2010 4:22 AM, Gregory Ewing wrote: John Nagle wrote: Arguably, if a function just does a "return", it should be an error to try to use its return value. It's been suggested at least once before that the default return value for a function should be some special value that raises an exception if you try to do anything with it except throw it away. Treating that case as an error would be consistent with the way attribute access works in Python. In Python, attempting to access a nonexistent attribute raises an exception. In Javascript, that returns a null. Javascript makes no distinction between "null" and "nonexistent", but Python does. It's un-Pythonic and inconsistent that functions which return nothing are considered to return a None object. John Nagle -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
The better question is, do I ever use them? Thinking back over the code I've written in the last couple of years, I would say probably two or three times (mostly in unit tests). I've had to code around string's sequence behavior DOZENS of times. Is it nifty that strings can be sliced like that? Sure. In general my experience has been that the string methods (and some misc functions in other modules) do a better job in simple cases, and regular expressions do a better job in complex cases. I just don't see string slicing having utility that is irreplaceable, and it is bug-inducing in many cases, or at the very least it can propagate programming errors way down stream. Ultimately, I highly doubt it's going anywhere, so it's a moot point. I definitely feel that python is trading real usability for "flash" with string slicing though. On Tue, Jul 13, 2010 at 8:48 PM, Aahz wrote: > [Original not available on my swerver, responding here] > > >On 7/11/10 10:03 PM, Nathan Rice wrote: > >> > >> Yeah, I long ago filed the in place place in the same folder as > >> strings-as-sequences, all() returning True for an empty iterable and any > >> returning True rather than the thing which triggered it. > > Because I love to repeat myself: > > "...string iteration isn't about treating strings as sequences of strings, > it's about treating strings as sequences of characters. The fact that > characters are also strings is the reason we have problems, but characters > are strings for other good reasons." --Aahz > http://mail.python.org/pipermail/python-3000/2006-April/000897.html > > Do you really want to give up Python's lovely string-slicing > capabilities? > -- > Aahz (a...@pythoncraft.com) <*> > http://www.pythoncraft.com/ > > "Normal is what cuts off your sixth finger and your tail..." --Siobhan > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
[Original not available on my swerver, responding here] >On 7/11/10 10:03 PM, Nathan Rice wrote: >> >> Yeah, I long ago filed the in place place in the same folder as >> strings-as-sequences, all() returning True for an empty iterable and any >> returning True rather than the thing which triggered it. Because I love to repeat myself: "...string iteration isn't about treating strings as sequences of strings, it's about treating strings as sequences of characters. The fact that characters are also strings is the reason we have problems, but characters are strings for other good reasons." --Aahz http://mail.python.org/pipermail/python-3000/2006-April/000897.html Do you really want to give up Python's lovely string-slicing capabilities? -- Aahz (a...@pythoncraft.com) <*> http://www.pythoncraft.com/ "Normal is what cuts off your sixth finger and your tail..." --Siobhan -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
John Nagle wrote: Arguably, if a function just does a "return", it should be an error to try to use its return value. It's been suggested at least once before that the default return value for a function should be some special value that raises an exception if you try to do anything with it except throw it away. Unfortunately, the existence of such a value would cause headaches for things like debuggers that need to be able to deal with anything at all without blowing up. -- Greg -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On 7/11/2010 5:24 PM, Steven D'Aprano wrote: On Sun, 11 Jul 2010 08:59:06 -0700, dhruvbird wrote: Why doesn't python's list append() method return the list itself? For that matter, even the reverse() and sort() methods? I found this link (http://code.google.com/edu/languages/google-python- class/lists.html) which suggests that this is done to make sure that the programmer understands that the list is being modified in place, but that rules out constructs like: ([1,2,3,4].reverse()+[[]]).reverse() Yes. So what? Where's the problem? List methods work in place. ... Not everything needs to be a one-liner. It's interesting that all Python functions are considered to return a value. Arguably, if a function just does a "return", it should be an error to try to use its return value. Some languages have a very functional orientation, and everything is considered to return some value, even control structures. LISP is like that. But Python isn't one of those languages. John Nagle -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Jul 12, 4:20 pm, Hrvoje Niksic wrote: > dhruvbird writes: > > No, I meant x.append(4) > > Except that I want to accomplish it using slices. > > > (I can do it as x[lex(x):] = [item_to_append] but is there any other > > way?) > > It seems that you've found a way to do so, so why do you need another > way? Are you after elegance? Efficiency? Brevity? Actually, the reason I ask is because I think a lot of things can be done using slices and its support for negative indexes. Basically putting constants in the slices (as opposed to variables like len(x), etc... which depend upon the variable name). So, was just trying to cogitate on whether append can be implemented that way or not. Regards, -Dhruv. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
Stephen: I'm not adverse to being able to do that, but the number of times that I've wanted to do that is greatly outweighed by the number of times I've had to pass a function "(somestring,)" or call "if isinstance(foo, basestring): ..." to avoid producing a bug. The more abstract and adaptive the code you are writing, the more annoying it gets - you end up with a rats nest of string instance checks and strings wrapped in tuples. Looking at my code, I don't have a lot of use cases for string slicing or iterating character by character. Most of the time I use the string methods, they're faster and (IMO) clearer - lower, index/rindex, find, etc. One use case that I avoid is extracting substrings, by slicing out the results of rfind. There's a good case for this but I feel it's brittle so I usually just jump to regular expressions (and it could be performed equally well with a substring method). That doesn't mean I don't think it's useful, just that as it stands the default language behavior is bug producing, and in my opinion people would be equally well served with an as_list method on strings that makes the behavior explicit. Chris: Let's not run around questioning people's math skills, that's actually my area of expertise, and it's impolite besides :) While having all([]) return True from a formal standpoint "makes sense" it typically reduces people to writing "if all(something) and something:", because feeding an iterable that has been filtered in some way (and thus has a range between 0 and n, where n is the length of the original iterable) is an incredibly common use case. In fact, I'm going to go out on a limb here and say there are a lot of bugs floating around that haven't been caught because the code author used all() under the assumption that it would be passed a non-empty list. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
dhruvbird writes: > No, I meant x.append(4) > Except that I want to accomplish it using slices. > > (I can do it as x[lex(x):] = [item_to_append] but is there any other > way?) It seems that you've found a way to do so, so why do you need another way? Are you after elegance? Efficiency? Brevity? Here are some other ways to express the same, and all use slices in some way: x[slice(len(x), None)] = [item_to_append] x.__setitem__(slice(len(x), None), [item_to_append]) x.__setslice__(len(x), len(x), [item_to_append]) ...but I have no idea why any of them would make any more sense than x[len(x):] = [item_to_append]. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Jul 12, 5:30 am, News123 wrote: > dhruvbird wrote: > > > On a side note, is there any other way to append to a list using > > slices (apart from the one below): > > x[len(x):len(x)] = [item to append] > > dy you mean > x.extend([1,2,3]) No, I meant x.append(4) Except that I want to accomplish it using slices. (I can do it as x[lex(x):] = [item_to_append] but is there any other way?) Regards, -Dhruv. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Sun, Jul 11, 2010 at 10:03 PM, Nathan Rice wrote: > Yeah, I long ago filed the in place place in the same folder as > all() returning True for an empty iterable If you weren't taught about vacuous truth (or even identity elements) in Discrete Mathematics, someone fscked up. Said behavior is the absolute correct behavior from a formal logic standpoint. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On 7/11/10 10:03 PM, Nathan Rice wrote: > Yeah, I long ago filed the in place place in the same folder as > strings-as-sequences, all() returning True for an empty iterable and any > returning True rather than the thing which triggered it. You know, the latter two I can see an argument for, and could see the usefulness therein -- though I've never used either like that, but I consider that chance. I could see the use (and could readily write my own all/any in such a case, then keep it in my toolbox). But the first: what?! for ch in data: is exceptionally useful. Strings-as-sequences I've used hundreds, thousands of times. I use it constantly. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
Yeah, I long ago filed the in place place in the same folder as strings-as-sequences, all() returning True for an empty iterable and any returning True rather than the thing which triggered it. Almost always annoying and worked around, but that's the price you pay for the other nice stuff :) It just takes writing a few hundred lines of Java code for me to shrug and forget about it. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Jul 11, 8:59 am, dhruvbird wrote: > Why doesn't python's list append() method return the list itself? For > that matter, even the reverse() and sort() methods? Because Guido thinks that having those methods return None is the best way to communicate that the underlying object has been mutated in- place. Some other languages do it differently, but this is Guido's language, so we do it his way. Raymond -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
dhruvbird wrote: > > On a side note, is there any other way to append to a list using > slices (apart from the one below): > x[len(x):len(x)] = [item to append] dy you mean x.extend([1,2,3]) ? -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Sun, 11 Jul 2010 08:59:06 -0700, dhruvbird wrote: > Why doesn't python's list append() method return the list itself? For > that matter, even the reverse() and sort() methods? I found this link > (http://code.google.com/edu/languages/google-python- class/lists.html) > which suggests that this is done to make sure that the programmer > understands that the list is being modified in place, but that rules out > constructs like: > ([1,2,3,4].reverse()+[[]]).reverse() Yes. So what? Where's the problem? List methods work in place. If you're annoyed now, that's *nothing* to the annoyance you'll feel if they returned the list and you did this: alist = [1,2,3] blist = alist.append(4) # Make a new list with 4 appended. assert alist == [1,2,3] > I want to prepend an empty list to [1,2,3,4]. This is just a toy > example, since I can always do that with [[]]+[1,2,3,4]. Or: L = [[]] L.extend([1,2,3,4]) Or: L = [1,2,3,4] L.insert(0, []) Not everything needs to be a one-liner. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Jul 11, 9:19 pm, Thomas Jollans wrote: > On 07/11/2010 05:59 PM, dhruvbird wrote: > > > Why doesn't python's list append() method return the list itself? For > > that matter, even the reverse() and sort() methods? > > I found this link (http://code.google.com/edu/languages/google-python- > > class/lists.html) which suggests that this is done to make sure that > > the programmer understands that the list is being modified in place, > > Yes! > > > but that rules out constructs like: > > ([1,2,3,4].reverse()+[[]]).reverse() > > No! > > you can either approach this by imperatively modifying a list in-place: > > L = [1,2,3,4] > L.reverse() > L.append([]) > L.reverse() > > Or you can use a more functional style: > > L2 = reversed(reversed([1,2,3,4]) + [[]]) Okay, but this assumes that I have reversed/sorted/etc... type of functions for all member functions that mutate the container. Also, as Nathan mentioned, reversed returns an iterator, whereas sorted returns a list. This asymmertic behaviour is a bit unnerving. > > (or ([1,2,3,4][::-1]+[[]])[::-1], if you like that kind of thing) > > Imagine list.reverse and list.append *did* return self: > > L1 = [1,2,3,4] > L2 = L1.reverse().append([]).reverse() > > would you expect, after this code, that (L1 == L2) and (L1 is L2)? I > think it would surprise a lot of people. Better clearly separate > modifying an object and functionally processing an object. I think this is a fair call. Honestly, I wouldn't expect them to be the same. However, there are cases when I want to be able to write down my intent in one line. Much like f(g(h(x))). On a side note, is there any other way to append to a list using slices (apart from the one below): x[len(x):len(x)] = [item to append] And while we are talking about python here, why does this statement: y = x[:0] = [100] behave the way it does? I mean everything except for the last value is assigned to the last value rather than the assignments following the chain and every item getting its succeeding item's reference? Regards, -Dhruv. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
Thomas Jollans wrote: On 07/11/2010 05:59 PM, dhruvbird wrote: Why doesn't python's list append() method return the list itself? For that matter, even the reverse() and sort() methods? I found this link (http://code.google.com/edu/languages/google-python- class/lists.html) which suggests that this is done to make sure that the programmer understands that the list is being modified in place, Yes! but that rules out constructs like: ([1,2,3,4].reverse()+[[]]).reverse() No! you can either approach this by imperatively modifying a list in-place: L = [1,2,3,4] L.reverse() L.append([]) L.reverse() [snip] If you want to prepend an empty list in-place, use the .insert method: L = [1,2,3,4] L.insert(0, []) -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On Sun, 11 Jul 2010 08:59:06 -0700 (PDT) dhruvbird wrote: > Why doesn't python's list append() method return the list itself? For > that matter, even the reverse() and sort() methods? > I found this link (http://code.google.com/edu/languages/google-python- > class/lists.html) which suggests that this is done to make sure that > the programmer understands that the list is being modified in place, > but that rules out constructs like: > ([1,2,3,4].reverse()+[[]]).reverse() > I want to prepend an empty list to [1,2,3,4]. This is just a toy > example, since I can always do that with [[]]+[1,2,3,4]. >>> x = [1,2,3,4] >>> y = [5,6] >>> x[:0] = y >>> x [5, 6, 1, 2, 3, 4] -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On 07/11/2010 06:28 PM, Nathan Rice wrote: > Do list(reversed(list(reversed([1, 2, 3, 4])) + [[]])) > > Though TBH sometimes get annoyed at this behavior myself. There are a > lot of people who are very vocal in support of returning none, and it > makes sense in some ways. Since reversed returns an iterator though, it > makes this code horrible and unreadable. > ah yes, forgot about that nuance. casting reversed to list. Still, there is slicing. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
Do list(reversed(list(reversed([1, 2, 3, 4])) + [[]])) Though TBH sometimes get annoyed at this behavior myself. There are a lot of people who are very vocal in support of returning none, and it makes sense in some ways. Since reversed returns an iterator though, it makes this code horrible and unreadable. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why doesn't python's list append() method return the list itself?
On 07/11/2010 05:59 PM, dhruvbird wrote: > Why doesn't python's list append() method return the list itself? For > that matter, even the reverse() and sort() methods? > I found this link (http://code.google.com/edu/languages/google-python- > class/lists.html) which suggests that this is done to make sure that > the programmer understands that the list is being modified in place, Yes! > but that rules out constructs like: > ([1,2,3,4].reverse()+[[]]).reverse() No! you can either approach this by imperatively modifying a list in-place: L = [1,2,3,4] L.reverse() L.append([]) L.reverse() Or you can use a more functional style: L2 = reversed(reversed([1,2,3,4]) + [[]]) (or ([1,2,3,4][::-1]+[[]])[::-1], if you like that kind of thing) Imagine list.reverse and list.append *did* return self: L1 = [1,2,3,4] L2 = L1.reverse().append([]).reverse() would you expect, after this code, that (L1 == L2) and (L1 is L2)? I think it would surprise a lot of people. Better clearly separate modifying an object and functionally processing an object. Cheers Thomas -- http://mail.python.org/mailman/listinfo/python-list
Why doesn't python's list append() method return the list itself?
Why doesn't python's list append() method return the list itself? For that matter, even the reverse() and sort() methods? I found this link (http://code.google.com/edu/languages/google-python- class/lists.html) which suggests that this is done to make sure that the programmer understands that the list is being modified in place, but that rules out constructs like: ([1,2,3,4].reverse()+[[]]).reverse() I want to prepend an empty list to [1,2,3,4]. This is just a toy example, since I can always do that with [[]]+[1,2,3,4]. Regards, -Dhruv. -- http://mail.python.org/mailman/listinfo/python-list