Непоследовательное поведение, объединяющее списки и кортежи в python - PullRequest
5 голосов
/ 30 мая 2019

Я заметил удивительное поведение при попытке объединить списки и кортежи.

Обычно они не смешиваются:

(0, 1) + [2, 3]

Результат:

TypeError: может только объединить кортеж (не «список») в кортеж

и наоборот

[0, 1] + (2, 3)

дает:

TypeError: может только объединить список (не "tuple") в список

Пока ничего неожиданного не было. Однако, если вы используете присвоение переменной через «+ =», поведение списков меняется!

l = [0, 1]
l += (2, 3)
l

1024 * дает *

[0, 1, 2, 3]

Но не для кортежей:

t = (0, 1)
t += [2, 3]
t

по-прежнему выдает ошибку:

TypeError: может только объединять кортеж (не "список") в кортеж

Конечно, здесь нет практической проблемы, но мне любопытно: Что там происходит?

Ответы [ 2 ]

8 голосов
/ 30 мая 2019

+= для списков не ожидает фактического списка в качестве его правого операнда; он примет любое итеративное значение. Это по сути операторская версия list.extend (которая также принимает произвольное итеративное значение).

tuple вообще не определяет __iadd__, поэтому t += [2, 3] - это просто синтаксический сахар для t = t + [2,3], и мы уже подтвердили, что tuple.__add__ не может добавить кортеж и список вместе.

2 голосов
/ 30 мая 2019

Каждая часть сама по себе имеет смысл, объединяя все вместе, как у вас бывает, чтобы выявить несоответствия.

Кортежи определяют __add__ и допускают объединение других кортежей.Имеет смысл, вы можете добавить две вещи одного типа вместе.То же самое для списков, вы можете + два списка вместе.

Кортежи неизменны, поэтому они не определяют __iadd__ (+=).

Списки изменяемые и определяют extend метод, , который принимает любой итеративный .Таким образом, вы можете делать такие вещи, как:

lst.extend(map(str, range(42)))

аккуратно и удобно.+= это в основном псевдоним для этого.

Итак:

  • tuple + tuple работает
  • list + list работает
  • tuple + listне работает, потому что они разных типов
  • list + tuple также не работает, как и ожидалось
  • list.extend / list += работает с любыми итерациями, включая кортежи
  • += для кортежей выполняется как a = a + b, потому что они неизменны, поэтому не работает, если a и b имеют разные типы
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...