【问题标题】:variable doesn't reset in while loop with function变量不会在带有函数的while循环中重置
【发布时间】:2015-01-10 12:58:03
【问题描述】:

我以前从未遇到过这种情况,想知道是否有人有解决方案。我有一个while循环,里面有一个返回整数的函数。该函数接受一个字符串和一个列表。 while 循环的第一次迭代返回正确的答案,但在随后的迭代中,即使函数没有以任何方式更改列表,列表似乎也是空的。此外,如果我尝试在 while 循环中的函数之后重置列表,则新列表似乎也为空。这似乎是一种非常奇怪的行为。任何关于发生了什么的解释将不胜感激。循环内的函数代码很长,所以在这个阶段我将避免发布它。但是,如果需要,我会发布。

 spectrum = [1,2,3,4,5,6]
 leaderboard = ['zzz','xxx','yyy']
 pep_scores = []
 j=0
 original_spectrum = spectrum
 print len(original_spectrum)
 while j < len(leaderboard):
      x= linear_score(leaderboard[j],spectrum)  #this function doesn't alter spectrum
      print leaderboard[j], x
      spectrum = original_spectrum     #should reset spectrum even though it shouldn't be necessary to do that
      print len(spectrum), len(original_spectrum) #prints 2 empty lists
      pep_scores.append(x) #appends correct score on 1st iteration and '0' for all others
      j=j+1

我添加了打印语句来尝试解决问题,我的原始代码在 while 循环中不包含“original_spectrum = spectrum”或“spectrum = original_spectrum”。我不明白为什么在 1 次迭代后 'origninal_spectrum' 是一个空列表。我没有发布该功能,因为我看不出它是如何导致问题的。如果您需要更多信息,请询问。

【问题讨论】:

  • original_spectrum = spectrum 创建副本。你确定linear_score 不会改变它的论点吗?没有完整的minimal example,很难提供帮助。
  • 谢谢,当我在循环之前将 original_spectrum 打印到屏幕上时,它与频谱完全相同?如果不是这种方式,我将如何创建副本。我 100% 确定该函数不会改变它的参数。 S抱歉,发布的内容很少,但该函数很长,并且包含其他几个也很长的嵌套函数
  • stackoverflow.com/q/2612802/3001761。如果你的代码很长,你应该把它减少到导致问题的最小部分——这将帮助你找到错误而无需询问。
  • Python references的可能重复

标签: python list function while-loop


【解决方案1】:

要创建列表的副本,请使用copy_list = original_list[:]

所以在你的例子中:

spectrum = [1,2,3,4,5,6]
leaderboard = ['zzz','xxx','yyy']
pep_scores = []
j=0
original_spectrum = spectrum[:]
print len(original_spectrum)
while j < len(leaderboard):
    x= linear_score(leaderboard[j],spectrum)  #this function doesn't alter spectrum
    print leaderboard[j], x
    spectrum = original_spectrum[:]     #should reset spectrum even though it shouldn't be necessary to do that
    print len(spectrum), len(original_spectrum) #prints 2 empty lists
    pep_scores.append(x) #appends correct score on 1st iteration and '0' for all others
    j=j+1

【讨论】:

  • 完美,似乎已经解决了。
【解决方案2】:

因为你在函数之外定义了 spectrum 并且它的作用域是全局的,当你将 spectrum 传递给你的函数作为它的列表名称时,它上面的任何 changes 都会改变它全局不是本地函数!请注意,它只是关于 mutable(如列表)对象。 (注意:标签是指向特殊内存地址的指针)(您的复制命令 original_spectrum = spectrum 只需为一个对象制作 2 个标签!!!

为了更好地理解,请参见以下示例:

>>> a=[1,2,3]
>>> def f(s):
...  s.remove(1)
... 
>>> f(a)
>>> a
[2, 3]

>>> def f(s):
...  s+=[1,2]
... 
>>> f(a)
>>> a
[2, 3, 1, 2]

现在你有两个选择:

  1. 复制spectrum 并将其传递给函数:

copy_spectrum = spectrum[:]

  1. 在函数内部定义spectrum,在外部定义一个以供全局使用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 2015-11-04
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    相关资源
    最近更新 更多