所以我正在做这个练习: 在给定的序列中,第一个元素应该成为最后一个元素。空序列或只有一个元素应该保持不变。所以我很快编写了一个函数,它使用append然后pop函数将第一个元素添加到末尾。然后弹出第一个元素。
from collections.abc import Iterable
def replace_first(x: list) -> Iterable:
x.append(x[0])
x.pop(x[0])
return x
print("Example:")
print(list(replace_first([1, 2, 3, 4])))
所以当我运行代码时它返回了:
Example:
[1, 3, 4, 1]
我所期待的:
Example:
[2, 3, 4, 1]
我认为这很奇怪,因为我的假设是 2 在追加后仍然具有 [1] 的索引。因此,我通过附加后的索引打印新列表的所有元素来测试这一点。
from collections.abc import Iterable
def replace_first(x: list) -> Iterable:
x.append(x[0])
print(x[0])
print(x[1])
print(x[2])
print(x[3])
print(x[4])
x.pop(x[0])
return x
print("Example:")
print(list(replace_first([1, 2, 3, 4])))
返回的
Example:
1
2
3
4
1
[1, 3, 4, 1]
所以我对到底发生了什么有点困惑。我打印的内容显示新索引正是我所期望的。 2 具有索引 [1],但是当对索引 [0] 使用 pop 函数时,它会删除 [1]。
我知道练习可以这样完成,
from collections.abc import Iterable
def replace_first(x: list) -> Iterable:
if x:
x.append(x.pop(0))
return x
但是我试图了解上面实例中的 pop 函数发生了什么。任何解释或推荐阅读将不胜感激。预先感谢。
当你有
x = [1, 3, 4, 1]
x[0]
的值为1
。所以
x.pop(x[0])
相当于
x.pop(1)
由于参数
list.pop()
是要删除的元素的索引,而不是值,因此这将删除列表的第二个元素。所以它删除了 3
,而不是 1
。
您必须使用
x.pop(0)
而不是 x.pop(x[0])
,就像您在问题末尾的较短版本中所做的那样。
按值移除的方法是
list.remove()
,所以
x.remove(x[0])
会做你想做的事,但效率有点低,因为它必须搜索值(尽管搜索保证很短,因为它是第一个元素)。