【问题标题】:list in Python3.6 [duplicate]Python3.6中的列表[重复]
【发布时间】:2018-02-16 01:00:03
【问题描述】:

我发现了一个关于列表的“有趣”问题。

list1 = [1, 2, 3]
list1.insert(3, list1)
print(list1)
[1, 2, 3, [...]]
POP = list1.pop()
print(POP)
[1, 2, 3]
list1.extend(['a', 'b', 'c'])
print(POP)
[1, 2, 3, 'a', 'b', 'c']

这些以交互模式显示。当然,我知道“插入”只能将一个对象插入到列表中。但是,当我将list1 插入list1 时。它显示[...],这是什么意思?而且POP = list1.pop(),那个pop不是只能返回最终的对象给你吗?扩展列表后,最终对象应为“c”。为什么它返回整个 list1 而没有 [...]

【问题讨论】:

  • 这不会发生在python3.6中...
  • @n33rma 一般来说,受骗的人还好……但是当人们开始为他们赞美上天时,你就知道出了问题。

标签: python python-2.7 python-3.x


【解决方案1】:

当您调用list1.insert(3, list1) 时,您将在索引3 处插入list1引用,因此您的列表变为:

[1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [...

您可以这样做:

>>> list1[3]
[1, 2, 3, [...]]
>>> list1[3][3]
[1, 2, 3, [...]]
>>> list1[3][3][3]
[1, 2, 3, [...]]
>>> list1[3][3][3][3]
[1, 2, 3, [...]]

您在其自身中无限嵌套了list1,这就是您看到[...] 的原因,因为列表无限长。

当您随后调用POP = list.pop() 时,您将删除引用,因此list1 再次变为[1, 2, 3]POP 成为@987654333 的引用 @。

因为POP 是对list1 的引用,所以当您调用list1.extend(['a', 'b', 'c']) 时,您还会将POP 更新为它们都指向同一个列表


如果你这样做了:

list1 = [1, 2, 3]
list1.insert(3, list1[:])

您正在添加list1副本,因此将获得:

[1, 2, 3, [1, 2, 3]]

然后调用:

POP = list1.pop()

将使POP 成为对列表的引用。

此时正在做:

list1.extend(['a', 'b', 'c'])
print(POP)

将输出:

[1, 2, 3]

和:

print(list1)

将输出:

[1, 2, 3, 'a', 'b', 'c']

或者,参考这张粗略的图纸(并不真正具有代表性):

【讨论】:

  • 这有点像罗素悖论吗?
  • @StephenFong 不,甚至远程都没有
  • 但是罗素的悖论谈到了一个包含自身的集合,因此是无限的
  • @Stephen 当然,但这些不是集合,这不是集合论
【解决方案2】:

基本上,Python 是基于引用的,因为当我们将一个对象分配给其他对象时,它的引用就会被复制。对于复制,您需要deepcopy 或在列表的情况下切片。下面是cmets中的解释。

list1 = [1, 2, 3]
#Creating list 1
list1.insert(3, list1)
#Inserting list1 refrence at index 3, means inserting its refernce. It would become [1, 2, 3, [1, 2, 3, [1, 2, 3, [... so on]]]]

print(list1)
[1, 2, 3, [...]]
#in order to avoid this write like list1.insert(3, list1[:])

POP = list1.pop()
#Here pop is removing last index from list and returing modified list too

print(POP)
[1, 2, 3]
list1.extend(['a', 'b', 'c'])
# Here you are extending some other list not its refrence as previous
print(POP)
[1, 2, 3, 'a', 'b', 'c']

【讨论】:

    【解决方案3】:

    写你的第一个问题。你是对的,insert 可以将单个元素添加到列表中。但是,该元素可以是任何东西——另一个数字、字符串、复杂对象、列表,甚至是列表本身。似乎 Python 足够聪明,可以确定打印 list1 会导致无限输出,因为 list1 具有类似的循环结构。所以它会打印一个类似于[...] 的占位符。


    写第二个问题。由于pop 返回列表中的最后一个元素,但该元素是对列表本身的引用,您将获得该引用。它还删除了引用,因此在您看来,您正在获得原始列表的副本。确实如此,但正如您所料,对象本身已经添加和删除了它的最后一个元素。

    【讨论】:

      猜你喜欢
      • 2018-02-21
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      相关资源
      最近更新 更多