Python:如何在数组中以“n”的步长有选择地切换布尔元素?

时间:2013-11-11 19:11:36

标签: python arrays boolean toggle

我在一行中有一串50个圣诞灯,当他们第一次插上电源时,所有灯都熄灭了。灯由一个按钮控制,每按一次按钮,一些灯就会翻转它们的状态(即如果它们关闭,它们会变为开;如果它们打开,它们会变为关闭状态)。更改灯光的选择取决于按钮按下的次数:

  • 在第1次按下时,第1,第2,第3,第4,......,第50个灯改变状态
  • 在第二次按下时,第二,第四,第六,......,灯会改变状态;
  • 在第3次按下,第3,第6,第9,......,灯改变状态;
  • 在第n次按下时,对应于n的所有倍数的灯会改变状态。

如何在任何给定数量的“n”按下之后找出哪些灯亮?

我尝试定义一个布尔数组来表示灯光。我写了以下函数:

lightsarray = [False] * 50 ### All lights are off at start ###

def pressbutton(n):
    count = 0

    for count in range(0, n):   
        lightsarray[::int(n)] = [not y for y in lightsarray[::int(n)]]
        count = count + 1
        return lightsarray

目前,n = 1的输出为True, True, True, True, True, True...

n = 2的输出为True, False, True, False, True, False...

到目前为止一切顺利。但是对于n = 3,我期待True, False, False, False, True, True, True...

但我得到了True, False, False, True, False, False...

我认为我在分配/获取数组状态时出错了。我该如何纠正?或者有更好的方法吗?

- 编辑 - 感谢大家的回复。我实现了这些更改,并且我得到了你建议的输出,但我不确定这是否符合预期的灯光状态。记住False = OFF和True = ON,让我们看看前5个灯。这是预期的:

对于0次按下,一切都已关闭:

False, False, False, False, False...

对于1次按下,每翻转1的灯都会翻转:

True, True, True, True, True...

对于2次按下,每2的倍数的灯都被翻转:

True, False, True, False, True...

请注意,第二和第四盏灯被切换,否则其余部分保持不变。

对于3次按下,每3的倍数灯都会被翻转:

True, False, False, False, True...

然而,在进行更改后,例如,2次按下会False, True...而不是True, False...,而3次按下会给True, True, False, False, False...(开头会有两个真相。)

我该如何纠正?我希望这是有道理的。

3 个答案:

答案 0 :(得分:1)

您的主要问题是您在同一功能中以多种方式使用计数。实质上,for count in range使用与count=0相同的变量,而count = count + 1正在修改循环变量。

另一个问题是,每次运行该函数时都要修改全局lightsarray,因此输出将取决于您以前如何使用该函数。

最后,如果您的pressbutton函数应该显示按下n按钮的结果,就像它看起来那样,您应该在每次循环迭代时更改不同的灯,而不是每次循环迭代都会翻转每n个亮点。

你应该这样做

def pressbutton(n):
    lightsarray = [False] * 50 ### All lights are off at start ###
    for count in range(0, n):
        lightsarray[::count] = [not y for y in lightsarray[::count]]
    return lightsarray

答案 1 :(得分:0)

如果我理解了进展,我会说对于每个步骤k,我们首先选择第k个元素,然后移动到第2个元素,3k,4k ...

这可以使用xrange(我更喜欢xrange到范围,因为它不会填充内存)来实现这一点。

这是一个这样的进展的例子

for k in xrange(1, n + 1):
    print range(k, n, k)

应该这样做,这是输出,看起来类似于你的例子:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 4, 6, 8]
[3, 6, 9]
[4, 8]
[5]
[6]
[7]
[8]
[9]
[]

请注意,你不必去n + 1,你可以在n:)停止。

答案 2 :(得分:0)

你开错了灯;你正在使用n,而不是count,循环计数器,所以你总是在错误的灯光下使用。

你需要从1开始计数,并计算到n(因此范围为'n + 1)。

你的缩进是错误的;你过早地返回 。取消return语句不要成为循环的一部分。

我还将lightsarray值作为函数本身的一部分,不要在这里使用全局,因为每次调用函数时它都会被突变,这使得测试函数本身变得更加困难

最后但并非最不重要的是,无需手动增加count,这就是for循环已经为您做的事情:

def pressbutton(n):
    lightsarray = [False] * 50 ### All lights are off at start ###
    for count in range(1, n + 1):   
        lightsarray[::count] = [not y for y in lightsarray[::count]]
    return lightsarray

现在这可以按预期工作:

>>> pressbutton(1)
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
>>> pressbutton(2)
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]
>>> pressbutton(3)
[True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True]