gpt4 book ai didi

python-3.x - [ :] in overwriting a list in a for loop? 的作用是什么

转载 作者:行者123 更新时间:2023-12-04 11:22:37 25 4
gpt4 key购买 nike

我今天在工作中遇到了一种奇怪的句法方法,我无法理解。假设我有以下列表:

my_list = [[1, 2, 3], [4, 5, 6]]
我的目标是根据某些标准过滤每个嵌套列表并覆盖列表中的元素。所以,假设我想从每个嵌套列表中删除奇数,使得 my_list包含偶数列表,最终结果如下所示:
[[2], [4, 6]]
如果我尝试使用简单的赋值运算符来执行此操作,则它不起作用。
my_list = [[1, 2, 3], [4, 5, 6]]
for l in my_list:
l = [num for num in l if num % 2 == 0]
print(my_list)

Output: [[1, 2, 3], [4, 5, 6]]
但是,如果我“切片”列表,它会提供预期的输出。
my_list = [[1, 2, 3], [4, 5, 6]]
for l in my_list:
l[:] = [num for num in l if num % 2 == 0]
print(my_list)

Output: [[2], [4, 6]]
我最初的假设是 l是一个新创建的对象,它实际上并未指向列表中的相应对象,而是比较 id(x[i]) 的输出, id(l) , 和 id(l[:]) (其中 ilx 中的索引),我意识到 l[:]是具有不同 ID 的那个。因此,如果 Python 在我分配给 l[:] 时正在创建一个新对象那么Python如何知道覆盖 l的现有对象? ?为什么这样做?为什么不是简单的赋值运算符 l = ...工作?

最佳答案

这是微妙的。
片段一:

my_list = [[1, 2, 3], [4, 5, 6]]
for l in my_list:
l = [num for num in l if num % 2 == 0]
为什么这不起作用?因为当你做 l = ,您只是重新分配变量 l ,不会对其值进行任何更改。
如果我们“手动”写出循环,希望这个策略失败的原因会变得更加清楚:
my_list = [[1, 2, 3], [4, 5, 6]]

# iteration 1
l = my_list[0]
l = [num for num in l if num % 2 == 0]

# iteration 2
l = my_list[1]
l = [num for num in l if num % 2 == 0]
片段二:
my_list = [[1, 2, 3], [4, 5, 6]]
for l in my_list:
l[:] = [num for num in l if num % 2 == 0]
为什么这样做?因为通过使用 l[:] = ,您实际上是在修改 l 的值引用,而不仅仅是变量 l .让我详细说明一下。
一般来说,使用 [:]列表上的符号(切片符号)允许人们使用列表的一部分。
最简单的用途是从列表中获取值;我们可以写 a[n:k]获取 n th, item n+1 st 项目等,直到 k-1 .例如:
>>> a = ["a", "very", "fancy", "list"]
>>> print(a[1:3])
['very', 'fancy']
Python 还允许在 = 的左侧使用切片符号。 .在这种情况下,它将符号解释为我们只想更新列表的一部分。例如,我们可以替换 "very", "fancy""not", "so", "fancy"像这样:
>>> print(a)
['a', 'very', 'fancy', 'list']
>>> a[1:3] = ["not", "so", "fancy"]
>>> print(a)
['a', 'not', 'so', 'fancy', 'list']
在使用切片语法时,Python 还提供了一些方便的速记。而不是写 [n:k] ,我们可以省略 nk或两者。
如果我们省略 n ,那么我们的切片看起来像 [:k] ,Python 将其理解为“最多 k”,即与 [0:k] 相同.
如果我们省略 k ,那么我们的切片看起来像 a[n:] ,Python 将其理解为“ n 及之后”,即与 a[n:len(a)] 相同.
如果我们都省略,那么两个规则都会发生,所以 a[:]a[0:len(a)] 相同,这是整个列表的切片。
例子:
>>> print(a)
['a', 'not', 'so', 'fancy', 'list']
>>> print(a[2:4])
['so', 'fancy']
>>> print(a[:4])
['a', 'not', 'so', 'fancy']
>>> print(a[2:])
['so', 'fancy', 'list']
>>> print(a[:])
['a', 'not', 'so', 'fancy', 'list']
至关重要的是,如果我们在 = 的左侧使用切片,这一切仍然适用。 :
>>> print(a)
['a', 'not', 'so', 'fancy', 'list']
>>> a[:4] = ["the", "fanciest"]
>>> print(a)
['the', 'fanciest', 'list']
并使用 [:]表示替换列表中的每个项目:
>>> print(a)
['the', 'fanciest', 'list']
>>> a[:] = ["something", "completely", "different"]
>>> print(a)
['something', 'completely', 'different']
好的,到目前为止一切顺利。
他们需要注意的关键是在列表的左侧使用切片表示法就地更新列表。换句话说,当我做 a[1:3] = ,变量 a永远不会更新;它引用的列表是。
我们可以通过 id() 看到这一点,正如你所做的那样:
>>> print(a)
['something', 'completely', 'different']
>>> print(id(a))
139848671387072
>>> a[1:] = ["truly", "amazing"]
>>> print(a)
['something', 'truly', 'amazing']
>>> print(id(a))
139848671387072
也许更恰本地说,这意味着如果 a是对其他对象中列表的引用,然后使用 a[:] =将更新该对象内的列表。像这样:
>>> list_of_lists = [ [1, 2], [3, 4], [5, 6] ]
>>> second_list = list_of_lists[1]
>>> print(second_list)
[3, 4]
>>> second_list[1:] = [2, 1, 'boom!']
>>> print(second_list)
[3, 2, 1, 'boom!']
>>> print(list_of_lists)
[[1, 2], [3, 2, 1, 'boom!'], [5, 6]]

关于python-3.x - [ :] in overwriting a list in a for loop? 的作用是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69302297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com