如何在 for 循环期间修改列表条目?

2024-11-26 08:36:00
admin
原创
176
摘要:问题描述:我知道在迭代循环期间修改列表是不安全的。但是,假设我有一个字符串列表,并且我想删除字符串本身。替换可变值算作修改吗?请参阅为什么修改迭代变量不会影响后续迭代?以了解相关问题:分配给迭代变量不会修改底层序列,也不会影响未来的迭代。解决方案 1:由于下面的循环仅修改已经看到的元素,因此它被认为是可以接受...

问题描述:

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


请参阅为什么修改迭代变量不会影响后续迭代?以了解相关问题:分配给迭代变量不会修改底层序列,也不会影响未来的迭代。


解决方案 1:

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

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]

因为它不需要创建临时列表并分配它来替换原始列表,尽管它确实需要更多的索引操作。

警告:虽然您可以通过这种方式修改条目,但是您无法更改其中的项目数,list否则可能会遇到问题。

下面是一个例子,说明我的意思——删除一个条目会从那一刻起扰乱索引:

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!

(结果是错误的,因为它没有删除所有应该删除的项目。)

更新

由于这是一个相当受欢迎的答案,这里是如何有效地“就地”删除条目(即使这不是真正的问题):

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

b[:] = [entry for entry in b if entry.strip() == entry]

print(b)  # -> ['a']  # CORRECT

请参阅如何在迭代时从列表中删除项目?。

解决方案 2:

这被认为是一种糟糕的形式。请使用列表推导式,如果需要保留对列表的现有引用,请使用切片赋值。

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

解决方案 3:

还有一个for循环变体,对我来说看起来比使用enumerate()的循环变体更干净:

for idx in range(len(list)):
    list[idx]=... # set a new value
    # some other code which doesn't let you use a list comprehension

解决方案 4:

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

您可以使用列表理解:

l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]

或者只执行C-stylefor 循环:

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

解决方案 5:

Ignacio Vazquez-Abrams 给出的答案非常好。可以通过这个例子进一步说明。想象一下:

  1. 向您提供了包含两个向量的列表。

  2. 您想遍历列表并反转每个数组的顺序。

假设您有:

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])]

解决方案 6:

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

如果您有一个知道可变的对象列表,那么您可以这样做,只要您不更改列表的实际内容。

因此你需要做某种类型的映射。如果你使用生成器表达式,它[操作]将在你迭代时完成,这样可以节省内存。

解决方案 7:

你可以做这样的事情:

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

这被称为列表推导,使您更容易在列表内循环。

解决方案 8:

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

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_strings 更改为 ['a', 'c', 'e']

解决方案 9:

简而言之,就是在迭代同一个列表时对列表进行修改。

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"]]

解决方案 10:

我刚刚发现的一些东西 - 当循环遍历可变类型(例如字典)列表时,你可以使用像这样的普通 for 循环:

l = [{"n": 1}, {"n": 2}]
for d in l:
    d["n"] += 1
print(l)
# prints [{"n": 2}, {"n": 1}]

解决方案 11:

在此示例中,目标是使用 Python 的“for”循环从整数数组中删除任何可以被 7 整除的元素:

def modify_array(numbers):
    for number in numbers:
        print ((number, numbers))
        if ((number % 7) == 0):
            numbers.remove(numbers[numbers.index(number)])
            modify_array(numbers)
    return (numbers)
            
numbers = [1, 2, 3, 4, 5, 6, 7, 14, 9, 77]
numbers = modify_array(numbers)

print(numbers)

上述“迭代递归”方法是有效的,因为执行普通的 for 循环会错过数组中的数字 14。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用