在列表中携带数字

时间:2016-03-31 12:35:36

标签: python-3.x

我正在制作一个代码猜测程序,要求输入一个示例键代码,然后程序会尝试字符组合并查找它需要多长时间。

我需要做的是有一个函数,它接收一个数字列表,并返回一个数字列表,最重要的是长度可以是任何东西。我目前有这个:

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]

此时我很困惑。我有什么问题吗?

2 个答案:

答案 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]