我正在制作一个代码猜测程序,要求输入一个示例键代码,然后程序会尝试字符组合并查找它需要多长时间。
我需要做的是有一个函数,它接收一个数字列表,并返回一个数字列表,最重要的是长度可以是任何东西。我目前有这个:
def increment(nums):
nums[len(nums) - 1] += 1
for i in range(len(nums)):
if nums[-i + 1] == 62:
nums[-i + 1] = 0
nums[-i] += 1
if nums[0] == 62:
return [0 for n in nums]
return nums
我试图使最后一个索引增加,当它达到62时,将秒增加到最后1,然后将最后一个设置为0,继续打开和继续。然后,当第一个数字达到62时,它返回一个零列表。
预期输出如下:
[0,0,0,1]
[0,0,0,2]
[0,0,0,3]
[0,0,0,4]
...
[0,0,0,61]
[0,0,1,0]
...
当前输出如下:
[0,0,0,1]
[0,0,0,2]
[0,0,0,3]
[0,0,0,4]
...
[0,62,0,0]
此时我很困惑。我有什么问题吗?
答案 0 :(得分:1)
进位循环中的索引关闭,当你想减去1和2时,你正在加1而不是:
def increment(nums):
nums[-1] += 1 # len(nums) - 1 is a slow verbose way to index at -1 in Python
for i in range(len(nums)):
if nums[-i - 1] == 62: # Change + 1 to - 1
nums[-i - 1] = 0 # Change + 1 to - 1
nums[-i - 2] += 1 # Change no adjustment to -2
if nums[0] == 62:
nums[:] = [0] * len(nums) # Always mutate argument to match return
return nums
当你遇到环绕式情况时(由于增量上的索引越界问题),这仍然会失败,并且它涉及比所需更多的小数学运算,所以我们可以通过调整来改进它并修复bug range
少运行一次,并删除两个索引修正:
# Run one fewer times, iterate as negative numbers directly, and start
# from -1, not 0 so no adjustment needed for two of three lookups
for i in range(-1, -len(nums), -1):
if nums[i] == 62:
nums[i] = 0
nums[i - 1] += 1
如果速度很重要,你可以用enumerate
更加聪明一点,所以你通常甚至都没有做索引,但这已经接近你已经拥有的东西了,过早的优化是所有邪恶的根源。 : - )
请注意,如果目标只是使迭代器按顺序生成此表单的list
,正如我在评论中提到的那样,the itertools
module提供了更简单的方法。出于内存原因,我们不能使用itertools.cycle
(最终会存储整个值的运行,其中大约有1500万个用于四个元素的情况),但我们可以使用chain
来模拟它:
from itertools import chain, product, repeat
carrygen = chain.from_iterable(product(range(62), repeat=4) for _ in repeat(None))
next(carrygen) # To skip all zero entry the first time around
carrygen = map(list, carrygen) # Returns lists instead of tuples
for nums in carrygen:
print(nums)
这将无限期地输出,直到你break
循环或杀死进程:
[0,0,0,1]
[0,0,0,2]
[0,0,0,3]
[0,0,0,4]
...
[0,0,0,61]
[0,0,1,0]
...
答案 1 :(得分:0)
我不认为你的列表索引在你的for循环中的运行方式与你期望的一样,但是我并没有尝试解决这个问题,我建议这对递归函数很有用: / p>
def increment(nums):
# Condition for ending the recursion when nums is empty
if not nums:
return []
# Check if we're overflowing the last item...
if nums[-1] < 61:
# ...if not, just increment it and return
nums[-1] += 1
return nums
else:
# ...if so, strip it off, increment the rest of the list, and
# tack on a 0 to the end
return increment(nums[:-1]) + [0]