【问题标题】:Inconsistent behavior concatenating lists and tuples in pythonpython中连接列表和元组的行为不一致
【发布时间】:2019-05-30 13:33:52
【问题描述】:

在尝试连接列表和元组时,我注意到一个令人惊讶的行为。

通常,它们不会混合:

(0, 1) + [2, 3]

结果:

TypeError:只能将元组(不是“列表”)连接到元组

反之亦然

[0, 1] + (2, 3)

给出:

TypeError:只能将列表(不是“元组”)连接到列表

到目前为止,没有什么出乎意料的。 但是,如果您通过“+=”使用变量赋值,列表的行为会发生变化!

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

给予

[0, 1, 2, 3]

但不适用于元组:

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

仍然产生错误:

TypeError:只能将元组(不是“列表”)连接到元组

当然,这里没有实际问题,但我很好奇: 那里发生了什么?

【问题讨论】:

  • 忘了说python版本:3.6.8
  • 请检查tuplelist 基本概念。 list 是不可变的,tuple 是不可变的。
  • @Harsha 它们都是不可变的……?!
  • @deceze 拼写错误:列表是可变的,元组是不可变的
  • @HarshaBiyani listinstance 是可变的; type list 本身不是。这就是我开玩笑的基础。

标签: python list tuples concatenation


【解决方案1】:

+= for lists 并不期望将实际列表作为其右手操作数;它将接受任何可迭代的值。它实际上是 list.extend 的运算符版本(接受任意可迭代值)。

tuple 根本没有定义__iadd__,所以t += [2, 3] 只是t = t + [2,3] 的语法糖,我们已经确认tuple.__add__ 不能同时添加一个元组和一个列表。

【讨论】:

    【解决方案2】:

    每个部分都是有意义的,将它们放在一起,因为你碰巧发现了不一致。

    元组定义__add__ 并接受其他元组连接在一起。有道理,您可以将两个相同类型的东西加在一起。列表也一样,你可以+ 两个列表一起使用。

    元组是不可变的,因此它们不定义__iadd__ (+=)。

    列表可变的并定义了一个extend 方法,它接受任何可迭代的。因此,您可以执行以下操作:

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

    简洁方便。 += 基本上是它的别名。

    所以:

    • tuple + tuple 工作
    • list + list 工作
    • tuple + list 不起作用,因为它们是不同的类型
    • 正如预期的那样,list + tuple 也不起作用
    • list.extend/list += 适用于任何可迭代对象,包括元组
    • 元组上的+=a = a + b 执行,因为它们是不可变的,因此如果ab 属于不同类型则不起作用

    【讨论】:

    • 这很有意义。我的回答错过了这一点:)
    • “元组是不可变的,所以它们没有定义 __iadd__ 好吧,这有点不合逻辑。元组可以实现__iadd__,以便+= 接受右侧的任何可迭代对象。毕竟,__iadd__ 并不需要就地修改元组。
    • 只是添加:t += 2,3 "works",但是创建了一个新的元组对象(因为元组是不可变的)。如果你在每一步之后使用id(t),你可以看到(假设是 C 实现)。
    • @Aran Faaair 已经足够了,但是 __iadd__ 的存在对于可变类型来说主要是有意义的,对于不可变类型来说意义不大。
    • @cdarke 是的,正如我所写,a = a + b 有效,如果 tuple + tuple 有效……
    猜你喜欢
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    相关资源
    最近更新 更多