Re: Passing a list into a list .append() method

2014-09-09 Thread Rustom Mody
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

2014-09-09 Thread JBB
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

2014-09-09 Thread JBB
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

2014-09-09 Thread Paul Kroeger
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

2014-09-09 Thread Peter Otten
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

2014-09-09 Thread JBB
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

2014-09-08 Thread Frank Millman

"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

2014-09-08 Thread JBB
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

2012-05-23 Thread Chris Kaynor
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

2012-05-23 Thread Dave Angel
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

2012-05-23 Thread Emile van Sebille

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

2012-05-23 Thread Karl Knechtel
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

2012-05-23 Thread Jean-Michel Pichavant

 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

2012-05-23 Thread ????????
>>> 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?

2010-07-16 Thread John Nagle

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?

2010-07-14 Thread Nathan Rice
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?

2010-07-13 Thread Aahz
[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?

2010-07-13 Thread Gregory Ewing

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?

2010-07-12 Thread John Nagle

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?

2010-07-12 Thread dhruvbird
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?

2010-07-12 Thread Nathan Rice
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?

2010-07-12 Thread Hrvoje Niksic
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?

2010-07-12 Thread dhruvbird
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?

2010-07-11 Thread Chris Rebert
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?

2010-07-11 Thread Stephen Hansen
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?

2010-07-11 Thread Nathan Rice
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?

2010-07-11 Thread Raymond Hettinger
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?

2010-07-11 Thread News123
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?

2010-07-11 Thread Steven D'Aprano
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?

2010-07-11 Thread dhruvbird
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?

2010-07-11 Thread MRAB

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?

2010-07-11 Thread Antoine Pitrou
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?

2010-07-11 Thread Thomas Jollans
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?

2010-07-11 Thread Nathan Rice
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?

2010-07-11 Thread Thomas Jollans
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?

2010-07-11 Thread dhruvbird
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