Python 如何在for循环期间修改列表项?

Python 如何在for循环期间修改列表项?,python,Python,现在我知道在迭代循环期间修改列表是不安全的。但是,假设我有一个字符串列表,并且我想去掉字符串本身。可变值的替换是否算作修改 这被认为是糟糕的表现。如果需要保留对列表的现有引用,请使用列表理解和切片分配 a = [1, 3, 5] b = a a[:] = [x + 2 for x in a] print(b) 这被认为是糟糕的形式。如果需要保留对列表的现有引用,请使用列表理解和切片分配 a = [1, 3, 5] b = a a[:] = [x + 2 for x in a] print(b)

现在我知道在迭代循环期间修改列表是不安全的。但是,假设我有一个字符串列表,并且我想去掉字符串本身。可变值的替换是否算作修改

这被认为是糟糕的表现。如果需要保留对列表的现有引用,请使用列表理解和切片分配

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)

这被认为是糟糕的形式。如果需要保留对列表的现有引用,请使用列表理解和切片分配

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
不,如果可以这样改变字符串,就不会改变列表的“内容”。但在Python中,它们是不可变的。任何字符串操作都会返回一个新字符串

如果你有一个你知道是可变的对象列表,你可以这样做,只要你不改变列表的实际内容

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
因此,您需要制作某种类型的地图。如果您使用生成器表达式,它[操作]将在您迭代时完成,您将节省内存。

不,如果您可以通过这种方式更改字符串,您不会更改列表的“内容”。但在Python中,它们是不可变的。任何字符串操作都会返回一个新字符串

如果你有一个你知道是可变的对象列表,你可以这样做,只要你不改变列表的实际内容

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)

因此,您需要制作某种类型的地图。如果使用生成器表达式,则[操作]将在迭代时完成,这样可以节省内存。

由于下面的循环仅修改已看到的元素,因此可以接受:

a = ['a',' b', 'c ', ' d ']

for i, s in enumerate(a):
    a[i] = s.strip()

print(a) # -> ['a', 'b', 'c', 'd']
这与:

a[:] = [s.strip() for s in a]
因为它不需要创建临时列表,也不需要分配临时列表来替换原始列表,尽管它确实需要更多的索引操作

注意:尽管您可以通过这种方式修改条目,但如果不冒遇到问题的风险,您无法更改
列表中的项数

下面是一个示例,我的意思是删除条目会从该点开始扰乱索引:

b = ['a', ' b', 'c ', ' d ']

for i, s in enumerate(b):
    if s.strip() != b[i]:  # leading or trailing whitespace?
        del b[i]

print(b)  # -> ['a', 'c ']  # WRONG!
(结果是错误的,因为它没有删除它应该拥有的所有项目。)

更新

由于这是一个相当流行的答案,下面介绍如何“就地”有效地删除条目(尽管这不是确切的问题):


请参阅。

由于下面的循环仅修改已看到的元素,因此可以认为它是可接受的:

a = ['a',' b', 'c ', ' d ']

for i, s in enumerate(a):
    a[i] = s.strip()

print(a) # -> ['a', 'b', 'c', 'd']
这与:

a[:] = [s.strip() for s in a]
因为它不需要创建临时列表,也不需要分配临时列表来替换原始列表,尽管它确实需要更多的索引操作

注意:尽管您可以通过这种方式修改条目,但如果不冒遇到问题的风险,您无法更改
列表中的项数

下面是一个示例,我的意思是删除条目会从该点开始扰乱索引:

b = ['a', ' b', 'c ', ' d ']

for i, s in enumerate(b):
    if s.strip() != b[i]:  # leading or trailing whitespace?
        del b[i]

print(b)  # -> ['a', 'c ']  # WRONG!
(结果是错误的,因为它没有删除它应该拥有的所有项目。)

更新

由于这是一个相当流行的答案,下面介绍如何“就地”有效地删除条目(尽管这不是确切的问题):


请参阅。

对于循环变量,我认为它比使用enumerate()的更干净:


还有一个for循环变量,在我看来比枚举()更干净:


您的问题不清楚决定删除哪些字符串的标准是什么,但如果您有或可以列出要删除的字符串,您可以执行以下操作:

my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
    for i in range(my_strings.count(undesirable_string)):
        my_strings.remove(undesirable_string)

这会将my_字符串更改为['a'、'c'、'e']

您的问题不清楚决定删除哪些字符串的标准,但如果您有或可以列出要删除的字符串,您可以执行以下操作:

my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
    for i in range(my_strings.count(undesirable_string)):
        my_strings.remove(undesirable_string)

这会将我的字符串更改为['a','c','e']

在迭代列表时修改每个元素是可以的,只要您不将添加/删除元素更改为列表

您可以使用列表理解:

l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]
或者只需对循环执行
C-style

for index, item in enumerate(l):
    l[index] = item.strip()

在迭代列表时修改每个元素是可以的,只要不将“添加/删除元素”更改为“列表”

您可以使用列表理解:

l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]
或者只需对循环执行
C-style

for index, item in enumerate(l):
    l[index] = item.strip()

您可以这样做:

a = [1,2,3,4,5]
b = [i**2 for i in a]

这称为列表理解,使您更容易在列表中循环。

您可以执行以下操作:

a = [1,2,3,4,5]
b = [i**2 for i in a]

这叫做列表理解,让你更容易在列表中循环。

杰姆希特·伊斯肯德洛夫和伊格纳西奥·巴斯克斯·艾布拉姆斯给出的答案非常好。这个例子可以进一步说明这一点:想象一下

a) 一个包含两个向量的列表将提供给您

b) 您希望遍历列表并反转每个数组的顺序

假设你有

v = np.array([1, 2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
    i = i[::-1]   # this command does not reverse the string

print([v,b])
你会得到

[array([1, 2, 3, 4]), array([3, 4, 6])]
另一方面,如果你这样做

v = np.array([1, 2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
   i[:] = i[::-1]   # this command reverses the string

print([v,b])
结果是

[array([4, 3, 2, 1]), array([6, 4, 3])]

杰姆希特·伊斯肯德洛夫和伊格纳西奥·巴斯克斯·艾布拉姆斯给出的答案非常好。这个例子可以进一步说明这一点:想象一下

a) 一个包含两个向量的列表将提供给您

b) 您希望遍历列表并反转每个数组的顺序

假设你有

v = np.array([1, 2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
    i = i[::-1]   # this command does not reverse the string

print([v,b])
你会得到

[array([1, 2, 3, 4]), array([3, 4, 6])]
另一方面,如果你这样做

v = np.array([1, 2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
   i[:] = i[::-1]   # this command reverses the string

print([v,b])
结果是

[array([4, 3, 2, 1]), array([6, 4, 3])]

简言之,在迭代同一列表时对列表进行修改

list[:] = ["Modify the list" for each_element in list "Condition Check"]
例如:

list[:] = [list.remove(each_element) for each_element in list if each_element in ["data1", "data2"]]

简言之,在迭代同一列表时对列表进行修改

list[:] = ["Modify the list" for each_element in list "Condition Check"]
例如:

list[:] = [list.remove(each_element) for each_element in list if each_element in ["data1", "data2"]]

字符串不是可变值。@user470379:列表元素是否可变与在列表中循环时修改它们是否安全无关。字符串不是可变值。@user470379:列表元素是否可变与修改列表是否安全无关在循环的过程中列出它们所处的位置。切片分配很聪明,而且