【问题标题】:Update list in Python class using a for loop使用 for 循环更新 Python 类中的列表
【发布时间】:2023-03-05 11:19:02
【问题描述】:

如果我有一个包含列表的 Python 类,在 for 循环中更新该列表的最佳方法是什么?

例如:

class Test:
    def __init__(self):
        self.values = [ 1, 2, 3 ]

    def does_not_work(self):
        for value in self.values:
            value += 1

    def this_works(self):
        for i, value in enumerate(self.values):
            self.values[i] += 1

    def works_too(self):
        new_values = []
        for value in self.values:
            value += 1
            new_values.append(value)
        self.values = new_values


t = Test()
print t.values
>> [ 1, 2, 3 ]

t.does_not_work()
print t.values
>> [ 1, 2, 3 ]

t.this_works()
print t.values
>> [ 2, 3, 4 ]

t.works_too()
print t.values
>> [ 3, 4, 5 ]
  • 选项 #1:更新列表中的值不会“坚持”,因此这显然不是正确的方法
  • 选项 #2:按预期工作,但需要 enumerate()
  • 选项 #3:使用更简单的 for 循环语法,但需要重新构建列表

我确信还有很多其他的方法(花哨的列表理解方法等)也可以工作,但我对可读性/清晰而不是简洁感兴趣。

注意:似乎有很多问题暗示了这一点,但(据我发现)大多数问题都包含在项目代码或特定问题中——我正在寻找一般的最佳实践答案。

【问题讨论】:

  • int 是不可变的。 value += 1 只是更改局部变量 value 所指的内容,然后在循环下次分配 value 时丢弃该对象。

标签: python list class oop


【解决方案1】:

这很好:

for i in range(len(list)):
    list[i] += sth

【讨论】:

  • 是的,我在我的问题中提到了上面的内容——想知道是否有更优雅的方式(但似乎没有)
【解决方案2】:

int 值是不可变的。

在选项 1 中,value += 1 只是将名称 value 分配给新对象,而不更改 self.values 中已有对象的任何内容。

在选项 2 中,您正在修改 列表 以引用新值,而不是现有值。

在选项 3 中,您将创建一个新列表,然后更改 self.value 以引用该列表。

在这三个选项中,您都没有更改self.values 中的任何现有值。


我可能只是创建一个带有列表理解的新列表:

self.values = [x + 1 for x in self.values]

但如果您想避免创建新列表,您可以使用切片分配重新分配给现有列表的每个元素。

self.values[:] = (x + 1 for x in self.values)

【讨论】:

  • 谢谢——这很奇怪/令人困惑,因为选项 #1 在 Java 中按预期工作,但在 Python 中却没有,这就是我最初困惑的来源。在我的特殊情况下,列表理解不是一个好的选择,因为我需要在循环内进行大量处理。
  • 我的 Java 知识已经过时了,但我记得,你不能在容器中存储原始(和不可变)int 值,只能存储可变 Integer 对象。跨度>
猜你喜欢
  • 1970-01-01
  • 2020-06-07
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 2014-02-22
相关资源
最近更新 更多