8

Python not support adding a tuple to a list:

>>> [1,2,3] + (4,5,6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list

What are the disadvantages for providing such a support in the language? Note that I would expect this to be symmetric: [1, 2] + (3, 4) and (1, 2) + [3, 4] would both evaluate to a brand-new list [1, 2, 3, 4]. My rationale is that once someone applied operator + to a mix of tuples and lists, they are likely to do it again (very possibly in the same expression), so we might as well provide the list to avoid extra conversions.

Here's my motivation for this question.

It happens quite often that I have small collections that I prefer to store as tuples to avoid accidental modification and to help performance. I then need to combine such tuples with lists, and having to convert each of them to list makes for very ugly code.

Note that += or extend may work in simple cases. But in general, when I have an expression

columns = default_columns + columns_from_user + calculated_columns

I don't know which of these are tuples and which are lists. So I either have to convert everything to lists:

columns = list(default_columns) + list(columns_from_user) + list(calculated_columns)

Or use itertools:

columns = list(itertools.chain(default_columns, columns_from_user, calculated_columns))

Both of these solutions are uglier than a simple sum; and the chain may also be slower (since it must iterate through the inputs an element at a time).

7
  • 2
    How about simply being consistent? Use tuples or use lists, but not both of them. Commented Mar 27, 2012 at 20:30
  • If it was supported at all I'd agree that would be the best behavior, but I think if someone does 2 + 'abc' they clearly want '2abc' so why not allow it, etc. etc. -- it's too much interpretation. Explicit is better than implicit. Commented Mar 27, 2012 at 20:30
  • 1
    You could simply use itertools.chain to chain your stuff and never use + instead. Commented Mar 27, 2012 at 20:32
  • I'd say that the weak point in your argument is the "they are likely to do it again". Commented Mar 27, 2012 at 20:39
  • You can't chain extends like that. You'd have to .extend(chain(...)). Commented Mar 27, 2012 at 20:42

3 Answers 3

12

This is not supported because the + operator is supposed to be symmetric. What return type would you expect? The Python Zen includes the rule

In the face of ambiguity, refuse the temptation to guess.

The following works, though:

a = [1, 2, 3]
a += (4, 5, 6)

There is no ambiguity what type to use here.

Sign up to request clarification or add additional context in comments.

16 Comments

I would expect the return to be a list, since once I start using + operator, it's likely I'll need to do it again. See my update to the question.
@max: I can't see why this should always return a list. I'm glad Python throws an error in such a situation, and I'm confident this won't ever change.
@max: You've asked Why does Python not support adding a tuple to a list. IMHO, Sven's answer nails this question.
@SvenMarnach Could you describe some circumstances under which you'd be happy that tuple + list raised an exception rather than silently work as I described?
This is CRAZY. List addition is NOT symmetric!!! A very simple/explicit semantic for sequence '+' is that is returns the type of its first arg. The function is ALREADY not symmetric. Seems a specious limitation to me.
|
2

Why python doesn't support adding different type: simple answer is that they are of different types, what if you try to add a iterable and expect a list out? I myself would like to return another iterable. Also consider ['a','b']+'cd' what should be the output? considering explicit is better than implicit all such implicit conversions are disallowed.

To overcome this limitation use extend method of list to add any iterable e.g.

l = [1,2,3]
l.extend((4,5,6))

If you have to add many list/tuples write a function

def adder(*iterables):
    l = []
    for i in iterables:
        l.extend(i)
    return l

print adder([1,2,3], (3,4,5), range(6,10))

output:

[1, 2, 3, 3, 4, 5, 6, 7, 8, 9]

7 Comments

He knows how to do it, he wants to know why he can't do it with +.
@agf: "and having to convert each of them to list makes for very ugly code". No, apparently he does not, because .extend() will not convert anything.
@RikPoggi He wants one long expression like [1] + (2,) + (3,) + [4] + (5,) to be able to be done at once without conversion or chain or anything like that without simplicity's sake. Any code that uses extend to do that in one line will be uglier than just that addition expression.
@RikPoggi "My rationale is that once someone applied operator + to a mix of tuples and lists, they are likely to do it again (very possibly in the same expression), so we might as well provide the list to avoid extra conversions." See his new edit to the question he clearly knows about extend.
Sorry, my fault for not writing more details in the original question. See the update.
|
1

You can use the += operator, if that helps:

>>> x = [1,2,3]
>>> x += (1,2,3)
>>> x
[1, 2, 3, 1, 2, 3]

You can also use the list constructor explicitly, but like you mentioned, readability might suffer:

>>> list((1,2,3)) + list((1,2,3))
[1, 2, 3, 1, 2, 3]

1 Comment

It does if I only have one tuple to add. I often have several objects, some tuples, some lists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.