python中for循环的范围问题

时间:2011-10-20 06:07:51

标签: python for-loop scope

在下面的代码中,当我使用它进行一系列操作后在第一个循环中打印行时,我看到了我想要的结果。但是,在我退出第一个循环后,我发现在变量Dataset中得到了不同的结果。我知道这是一个范围问题,但我无法弄清楚问题是什么以及如何获得我想要的结果,这是用第一个“print”语句显示的。谢谢你的帮助

import random
random.seed(1234567)
Key=[[.5,.5]]
Dataset=[[0]+[0]*1]*int(10/2) +[[1]+[0]*1]*int(10/2)

print "results I need"
for row in Dataset:
    response=row[0]
    for i in xrange(len(Key)):
        if random.random() < Key[i][response]: 
            row[i+1]=response
        else: 
            row[i+1]=1-response
    print row

print "Results I get"
for row in Dataset:
    print row

4 个答案:

答案 0 :(得分:3)

  • Python具有引用语义。您的原始Dataset包含对常见[0, 0][1, 0]子列表的多个引用。 (我也很难理解为什么你的初始化如此复杂。)

您可以使用[[0, 0] for i in xrange(5)] + [[1, 0] for i in xrange(5)]修复此问题。

  • 你的其余逻辑也是不必要的复杂。我们可以使用条件表达式将两个赋值合并在一起,我们应该使用直接迭代而不是迭代一个人为的索引列表(xrange)。

看起来像:

for row in Dataset:
    response = row[0]
    for k in Key:
        row[i + 1] = response if random.random() < k[response] else 1 - response
  • 但是,这仍然不是我们正在寻找的解决方案。实际上没有理由将所有那些零都放在初始化数据中,这些初始化数据将被覆盖并且永远不会在循环中读取。 [i + 1]索引也很笨拙。一个更简单的解决方案:从列表中仅列出子列表的第一个值,并在循环内构建每个子列表的其余部分(我们可以使用列表解析)并添加第一个元素。我们可以使用另一个列表理解来将它们绑定在一起,而不是替换Dataset的元素。

这给了我们:

import random
random.seed(1234567)
Key=[[.5,.5]]
Initial_Conditions=[0]*int(10/2) +[1]*int(10/2)

Dataset = [
    [i] + [
        i if random.random() < k[i] else 1 - i
        for k in Key
    ]
    for i in Initial_Conditions
]

答案 1 :(得分:2)

这根本不是一个范围问题。你误解了Dataset,导致它由两组5个引用组成的同一个列表组成。

Dataset = [[0]+[0]*1 for x in range(10//2)] + [[1]+[0]*1 for x in range(10//2)]

答案 2 :(得分:0)

问题在于如何构建数据集。它的内容并非都是唯一的列表 - 其中几个是完全相同的对象(不仅仅是相同的内容)。这很容易解决:

Dataset=[[0,1] for i in range(10//2)] + [[1,0] for i in range(10//2)]

答案 3 :(得分:0)

这不是范围问题,我认为他想更新数据集,

请参阅下面的修改过的脚本

import random
random.seed(1234567)
Key=[[.5,.5]]
Dataset=[[0]+[0]*1]*int(10/2) +[[1]+[0]*1]*int(10/2)

print "results I need"
for row in range(len(Dataset)): # Changes
    response=Dataset[row][0]
    for i in xrange(len(Key)):
        if random.random() < Key[i][response]:
            Dataset[row][i+1]=response # Important
        else:
            Dataset[row][i+1]=1-response # Important
    print Dataset[row]

print "Results I get"
for row in Dataset:
    print row