【问题标题】:Update value of variable in a list - Python更新列表中变量的值 - Python
【发布时间】:2018-07-04 22:00:24
【问题描述】:

在开发一个项目时,我在 Python 中发现了一个奇怪的错误。 例如:

#Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32

variable = "Hello_1"
list = ["This is a variable -> ",variable]
print list #-> ["This is a variable -> " , "Hello_1"]

现在,我将变量修改为新值。所以,我想当改变变量的值时,我会在列表中看到新的值

variable = "Hello_2"
print list #-> ["This is a variable -> " , "Hello_1"]

但是,输出和第一次一样吗?有人知道怎么解决吗?

【问题讨论】:

  • 列表中的variable是副本;因为它是原始类型,所以它是按值复制的,而不是“引用”,就好像它是一个对象一样。另外,不要命名您的list...列表...
  • 列表和变量之间没有动态链接。定义列表后,对变量的任何更改都不会反映回列表。
  • 总结一下:这不是错误。一般经验法则:如果您认为在底层编程语言中发现了错误,那么您很可能没有:首先检查您的代码和您的理解:)
  • @bedwyr 是的,但一开始就假设它是一个错误可能会成为试图了解正在发生的事情并最终导致假设这是一个误解的动机:)
  • @Alfe,同意激励理解是一件好事。也就是说,我见过很多知识较少的开发人员认为语言中存在问题,然后开始尝试解决它:D

标签: python


【解决方案1】:

图片变量与列表没有任何链接。

str、int、float 和 tuple 不可编辑。列表和字典是可编辑的。因此,如果您使用列表或字典,那么它会随处变化。

当使用列表而不是变量时,请参阅此示例

variable = ["Hello_1"]
lis = ["This is a variable -> ",variable]
print lis #-> ["This is a variable -> " , "Hello_1"]
variable[0] = "Hello_2"
print lis #-> ["This is a variable -> " , "Hello_2"]

打印出来

['这是一个变量 -> ', ['Hello_2']]

【讨论】:

    【解决方案2】:

    Python 字符串是纯值,在赋值时,它们会被逻辑复制。 (也许在内部使用一些写时复制功能更智能,但对于 Python 开发人员来说,这从未显示出来。)

    您想要的是对字符串的引用。这在 Python 中不存在。

    最接近它的方法是使用包含单个元素的列表。由于列表是通过引用复制的,因此它们可以模拟您的预期:

    variable = ["Hello_1"]
    list = ["This is a variable -> ",variable]
    print list #-> ["This is a variable -> " , ["Hello_1"]]
    variable[0] = "Hello_2"  # assign to element of list
    print list #-> ["This is a variable -> " , ["Hello_2"]]
    

    但是,拜托,因为这很难理解代码并且远非 Pythonic,所以我发布这个只是为了提高对 Python 中正在发生的事情的理解。我不建议使用此功能,至少不适合初学者。最好接受字符串在分配时被复制(至少在逻辑上),并找到一种方法来使用它来编程你需要的东西。

    【讨论】:

    • Python 字符串不会在赋值时被复制。但是当为变量分配新值时,引用会更改为指向该新值。对旧值的其他引用(例如列表中的那个)被单独保留。
    • @das-g 我认为你错了。逻辑上,字符串在分配时被复制。在a = b 之后,b 代表的值被复制,a 将保留该值,无论b 发生什么情况。如果b 是像"abcde"[2:4] 这样的复杂术语,则逻辑复制变得更加明显。我还写道,在内部可以避免复制,但对于程序员的理解,这无关紧要。
    • 让我重新表述一下: python 对象在赋值时被复制,无论其类型如何,无论 Python 实现如何(只要实现兼容)。只有引用被复制。由于字符串是不可变的,因此很难将其与特定于实现的优化(如实习/常量池和可能的其他优化)区分开来,这些优化可能在某些情况下应用于某些实现,但不适用于其他实现。使用可变对象(例如列表),它会变得更加明显。如果你做a = b,你不仅保证a == b,而且保证a is b
    • 对于"abcde"[2:4],至少在概念上,新的字符串对象(如果有的话)是由切片创建的,而不是通过任何赋值创建的。对于字符串复制,请参阅stackoverflow.com/q/24804453/674064stackoverflow.com/q/2123925/674064。对于 Python 的参考语义 w.r.t。分配,见stackoverflow.com/q/11222440/674064
    • 您会同意a = bb = 5 之后会复制值​​5。我从未说过复制了对象。对于对象,仅传递引用。但是对于原语(如数字和字符串),值是在逻辑上被复制的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    相关资源
    最近更新 更多