Почему я не могу добавить кортеж в список с помощью оператора «+» в Python? - PullRequest
4 голосов
/ 28 марта 2012

Python не поддерживает добавление кортежа в список:

>>> [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

Каковы недостатки для предоставления такой поддержки в языке?Обратите внимание, что я ожидал бы, что это будет симметрично: [1, 2] + (3, 4) и (1, 2) + [3, 4] оба приведут к совершенно новому списку [1, 2, 3, 4].Мое обоснование состоит в том, что, как только кто-то применяет оператор + к совокупности кортежей и списков, он, скорее всего, сделает это снова (очень вероятно, в том же выражении), поэтому мы могли бы также предоставить список, чтобы избежать дополнительных преобразований.

Вот моя мотивация для этого вопроса.

Часто случается, что у меня есть небольшие коллекции, которые я предпочитаю хранить в виде кортежей, чтобы избежать случайных изменений и повысить производительность.Затем мне нужно объединить такие кортежи со списками, и необходимость преобразования каждого из них в список приводит к очень уродливому коду.

Обратите внимание, что += или extend могут работать в простых случаях.Но в целом, когда у меня есть выражение

columns = default_columns + columns_from_user + calculated_columns

, я не знаю, какие из них являются кортежами, а какие списками.Поэтому мне нужно либо преобразовать все в списки:

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

, либо использовать itertools:

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

Оба эти решения уродливее, чем простая сумма;и chain также может быть медленнее (поскольку он должен перебирать входы элемента по одному за раз).

Ответы [ 3 ]

10 голосов
/ 28 марта 2012

Это не поддерживается, поскольку оператор + должен быть симметричным. Какой тип возврата вы ожидаете? Python Zen включает в себя правило

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

Тем не менее, следующие работы:

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

Нет никакой двусмысленности, какой тип использовать здесь.

2 голосов
/ 28 марта 2012

Почему python не поддерживает добавление разных типов: простой ответ заключается в том, что они бывают разных типов, что если вы попытаетесь добавить итерируемое и ожидать появления списка?Я сам хотел бы еще раз повторить.Также рассмотрите ['a','b']+'cd' что должно быть на выходе?учитывая, что явное лучше, чем неявное все такие неявные преобразования запрещены.

Чтобы преодолеть это ограничение, используйте extend метод списка, чтобы добавить любую итерацию, например

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

Если вам нужно добавить много списков / кортежей, напишите функцию

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]
1 голос
/ 28 марта 2012

Вы можете использовать оператор +=, если это помогает:

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

Вы также можете явно использовать конструктор списка, но, как вы упомянули, читаемость может пострадать:

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