【问题标题】:Replace all values in a list without using enumerate?替换列表中的所有值而不使用枚举?
【发布时间】:2019-02-09 23:57:06
【问题描述】:

假设我想在列表中找到所有值“6”并将其替换为值“600”。我可以使用 enumerate() 来完成此操作,但我相信这不是做我想做的事的好方法。我面临的问题是我需要知道索引才能用新的值替换值,因此是 DATA[idx] 。

DATA = [ 2,4,6,8,6,1,2,3,4,6]
      for idx, val in enumerate(DATA):
        if val == 6:
            DATA[idx]=600

但是是否有替代和/或更有效的方法来做到这一点?感谢您的宝贵时间。

【问题讨论】:

  • 如果您解释一下您的意思是什么效率,那将非常有帮助。
  • 为什么你认为枚举不是一个好工具?有时你确实需要值和索引。

标签: python python-3.x loops for-loop enumerator


【解决方案1】:

我不确定您所说的“更高效”是什么意思。您所能做的就是遍历数组并考虑每个值。您的代码充分地做到了这一点。我看不出有什么问题。

我可以想到许多其他方法来做到这一点。列表推导非常紧凑:

   DATA = [600 if i == 6 else i for i in DATA]

这确实创建了一个新数组,因此可以说它的效率有点低。我想不出一种更紧凑的方式来遍历列表并更改其中的条目。

【讨论】:

  • 哎呀。有人打败了我的答案。我们同意,所以这绝对是你的答案:)
  • 这将创建一个新列表,这与 OP 的代码不同。如果您有多个变量指向原始列表,这样做会导致问题。
【解决方案2】:

使用列表推导:

DATA = [2,4,6,8,6,1,2,3,4,6]
DATA = [600 if x == 6 else x for x in DATA]
print(DATA)
>> [2, 4, 600, 8, 600, 1, 2, 3, 4, 600]

编辑:根据要求——顺便说一句,我不太确定这是否正是 Python 在后台实现它的方式,但这是理解的简化版本:

>>>> DATA = [600 if x == 6 else x for x in DATA]
DATA2 = []
for x in DATA:
    if x == 6:
        DATA2.append(600)
    else:
        DATA2.append(x)
DATA = DATA2
del(DATA2)

【讨论】:

  • 嘿AK47,你能不能重写一下[600 if x == 6 else x for x in DATA]?我不熟悉这些语句的快捷版本。
  • 对于列表 DATA 中的每个值,如果 x == 6,则使用值 600,否则只使用 x 的原始值
  • @Mike:您所指的语法在 Python 中称为列表理解。这是给你的参考链接:treyhunner.com/2015/12/python-list-comprehensions-now-in-color
  • 这将创建一个新列表,这与 OP 的代码不同。如果您有多个变量指向原始列表,那么这样做会导致问题。将列表重新分配给原始名称不会解决问题;它仍然是一个不同的列表。
  • @AK47 - 创建新列表时,您没有替换原始列表中的任何值。我建议您阅读有关可变对象如何工作的内容。你和史蒂夫的答案,就他们的立场而言,与 OP 的代码有不同的结果,因此对任何认为它们是临时替代品的人都是有害的。
【解决方案3】:

您可以将rangelen 一起使用:

for i in range(len(DATA)):
    if DATA[i] == 6:
        DATA[i] = 600

或切片赋值:

DATA[:] = [600 if item == 6 else item for item in DATA]

enumerate 可能是最好的。

【讨论】:

  • LHS 上的切片有什么用?我猜你认为这更有效,因为它修改了原始列表而不是替换它。但实际上并没有什么不同,因为 RHS 无论如何都会创建一个新列表。这只是新列表如何变为 DATA 的问题,我担心您对原始列表的操作方式可能会降低效率。这取决于编译器。
  • @Steve - 切片分配将所有重新计算的元素放入原始列表中,就像 OP 的代码一样,但您的答案没有。如果一段代码产生了对该列表的多个引用并希望它们保持不变,那么创建和分配一个新列表可能会导致错误。
  • 酷。没想到。我会记住这个以备将来使用。谢谢!
【解决方案4】:

对于您的任务,最好使用NumPyboolean mask 通过直观的命令进行非常快速方便​​的就地替换

                              data[data == 6] = 600

完整代码:

import numpy as np            # pip install numpy

DATA = [ 2,4,6,8,6,1,2,3,4,6]

data = np.array(DATA)         # converting to a NumPy array
data[data == 6] = 600         # data == 6 is a boolean mask; it is written in [] as an index

print(data)的输出:

 [  2   4 600   8 600   1   2   3   4 600]

注 1:

如果您需要将生成的 NumPy 数组转换回 Python 列表,请使用 data = list(data)

[2, 4, 600, 8, 600, 1, 2, 3, 4, 600]

注2:

将名称 DATA(全部大写)用于您稍后将更改的内容会令人困惑 -
请参阅PEP 8 - Style Guide for Python Code 和其中的Constants 部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 2022-07-03
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多