[Python-bugs-list] [ python-Bugs-575536 ] Concatenating a tuple to a list
noreply@sourceforge.net
noreply@sourceforge.net
Sun, 30 Jun 2002 12:42:58 -0700
Bugs item #575536, was opened at 2002-06-29 19:18
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=575536&group_id=5470
Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Dan Grassi (dgrassi)
>Assigned to: Guido van Rossum (gvanrossum)
Summary: Concatenating a tuple to a list
Initial Comment:
"a=a+b" is not the same as "a+=b" if a is a list and b is a tuple. See the code below.
This has been tested on 2.2.1 MacPython, 2.2 MachoPython and 2.2 Python on an Alpha.
Augmented assignment (+=) with a list on the LHS allows a tuple on the RHS. Standard assignment does not.
This seems intuitively wrong.
--- test code ---
a=[1]
b=(2,)
print 1,type(a), a
print 1,type(b), b
c=a+b
print 2,type(a), a
print 2,type(b), b
a=a+b
print 3,type(a), a
print 3,type(b), b
a+=b
print 4,type(a), a
print 4,type(b), b
Below is the execution results of the above:
>>>
>>> a=[1]
>>> b=(2,)
>>>
>>> print 1,type(a), a
1 <type 'list'> [1]
>>> print 1,type(b), b
1 <type 'tuple'> (2,)
>>> c=a+b
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "tuple") to list
>>>
>>> print 2,type(a), a
2 <type 'list'> [1]
>>> print 2,type(b), b
2 <type 'tuple'> (2,)
>>> a=a+b
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "tuple") to list
>>>
>>> print 3,type(a), a
3 <type 'list'> [1]
>>> print 3,type(b), b
3 <type 'tuple'> (2,)
>>> a+=b
>>>
>>> print 4,type(a), a
4 <type 'list'> [1, 2]
>>> print 4,type(b), b
4 <type 'tuple'> (2,)
>>>
----------------------------------------------------------------------
>Comment By: Raymond Hettinger (rhettinger)
Date: 2002-06-30 14:42
Message:
Logged In: YES
user_id=80475
GvR, please pronounce.
1. liberalize list_concat to match list_inplace_concat,
2. restrict list_inplace_concat to match list_concat, or
3. declare it fine the way it is.
While you're at it, pronounce for tuples also. Timbot
makes a good argument that they should be left alone.
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2002-06-30 14:37
Message:
Logged In: YES
user_id=80475
I have zero emotional attachment to this. Do whatever you
think best: accept it, close it, or assign to GvR to get a
pronouncement for alltime.
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2002-06-30 14:31
Message:
Logged In: YES
user_id=31435
Dueling edits.
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2002-06-30 14:25
Message:
Logged In: YES
user_id=31435
The intent was that list.__iadd__ correspond exactly to
list.extend(). There's no need to hypergeneralize
list.__add__() too: it's a feature that people who don't
want to get surprised by Martin-like examples can avoid
them by using plain + for lists.
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2002-06-30 14:08
Message:
Logged In: YES
user_id=80475
One other thought -- list.__add__ 's behavior should
correspond closely to list.extend():
>>> a = [1]
>>> a.extend((2,3))
>>> a.extend({4:5})
>>> a
[1, 2, 3, 4]
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2002-06-30 14:04
Message:
Logged In: YES
user_id=31435
This is all intentional. Lists choose to implement
list += whatever
as a synonym for
list.extend(whatever)
and whatever can be any iterable object in both. It's A
Feature that mutable objects can choose to do something
different for += than for +.
Trying to make tuples do this too is a bad idea -- there is
no tuple.extend(), and there can't be because tuples are
immutable.
Lists and tuples differ here. If they were the same thing,
there wouldn't be much point to having both <wink>.
I recommend closing as WontFix, although it's quite
possible the docs could be improved (haven't looked).
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2002-06-30 14:00
Message:
Logged In: YES
user_id=80475
Agreed. My first instinct was to restrict list_inplace_concat
() rather than liberalize list_concat(); however, it is already
out in the wild and code may be relying on it.
One change or the other should be made since the docs
promise that 'a op= b' is equivalent to 'a = a op b' unless
specifically overriden or when get/set attr is used to
access 'a'.
Your example highlights the weirdness that can ensue;
however, I think we already started down that road when
everything was made iterable and, therefore, substitutable
into weird combinations:
>>> zip([1], 'hallo', {1:2})
[(1, 'h', 1)]
----------------------------------------------------------------------
Comment By: Martin v. Löwis (loewis)
Date: 2002-06-30 13:43
Message:
Logged In: YES
user_id=21627
I'm not so sure that the current += behaviour is desirable.
It means that
a=[1]
a+="hallo"
a+={1:2}
is possible, which should be a TypeError, IMO.
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2002-06-30 11:35
Message:
Logged In: YES
user_id=80475
Confirmed. The behavior of list_inplace_concat diverged
from list_concat.
See attached patch. Recommend applying to Py2.3 only
since inconsistency isn't a bug.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=575536&group_id=5470