全局变量在循环中重置?

时间:2015-12-09 20:59:28

标签: python list for-loop append

我试图从advent of code处理问题,而我似乎无法破解它。它应该收集一组唯一的坐标,然后输出它们的计数。我的主变量coords_list在for循环之外实例化,然后添加到for内部。

出于某种原因,每次我在for内追加它时,它似乎都会'重置',所以最多我的返回列表是coords_list的初始值列表,加上我附加的最新值。

我很可能只是错过了一些简单的东西。不过,任何帮助都会很棒。

输出

coords_list: [[0, 0]]
START -- coords: [0, 0], vector: (1, 0), instruction: >
END -- coords: [1, 0], coords_list: [[0, 0], [1, 0]]
input: >, len: 2
------
coords_list: [[0, 0]]
START -- coords: [0, 0], vector: (0, 1), instruction: ^
END -- coords: [0, 1], coords_list: [[0, 0], [0, 1]]
START -- coords: [0, 1], vector: (1, 0), instruction: >
END -- coords: [1, 1], coords_list: [[0, 0], [1, 1]]
START -- coords: [1, 1], vector: (0, -1), instruction: v
END -- coords: [1, 0], coords_list: [[0, 0], [1, 0]]
START -- coords: [1, 0], vector: (-1, 0), instruction: <
END -- coords: [0, 0], coords_list: [[0, 0], [0, 0]]
input: ^>v<, len: 2
------
Traceback (most recent call last):
  File "python", line 47, in <module>
AssertionError

代码

def return_vector(chary):

    if chary == "^":
        ret_value = (0,1)
    elif chary == "v":
        ret_value = (0,-1)
    elif chary == ">":
        ret_value = (1, 0)
    elif chary == "<":
        ret_value = (-1, 0)
    else:
        raise ValueError("Expecting one of '^','v','>','<', got {}".format(chary))

    return ret_value

def main(input):
    coords_list = [[0,0]]
    coords = [0,0]
    lst_input = list(input)
    debug_iterator, debug_loop = 0, 10
    print("coords_list: {}".format(coords_list))

    for instruction in lst_input:
        vector = return_vector(instruction)


        if debug_iterator < debug_loop:
            print("START -- coords: {}, vector: {}, instruction: {}".format(coords, vector, instruction))

        coords[0] += vector[0]
        coords[1] += vector[1]

        if coords not in coords_list:
            coords_list.append(coords)

        if debug_iterator < debug_loop:
            print("END -- coords: {}, coords_list: {}".format(coords, coords_list))
            debug_iterator += 1

    print('input: {}, len: {}\n------'.format(input, len(coords_list)))
    return(len(coords))

assert main('>') == 2
assert main('^>v<') == 4
assert main('^v^v^v^v^v') == 2

print("main(INPUT) == {}".format(main(INPUT)))


assert return_vector('^') == (0,1)

1 个答案:

答案 0 :(得分:1)

当您编写coords_list.append(coords)时,您将附加一个coords对象的引用,然后您可以更改该对象。相反,你想要一份副本。您可以使用coords[:]执行此操作,但在此处使用不可变tuplenamedtuple会更合适。 <怎么样

def main(inp):
    coords = set()
    cur = (0, 0)
    coords.add(cur)
    for instruction in inp:
        vector = return_vector(instruction)
        cur = (cur[0] + vector[0], cur[1] + vector[1])
        coords.add(cur)
    return len(coords)

请注意其他一些变化:

  • coords_list实际上更像是一套。重命名为coords并制作了一套。这简化了添加,并使大型坐标集的成员资格测试更快。
  • that is a built-in
  • 重命名input
  • list(input)已经对输入进行了迭代。然后迭代列表。相反,只需在输入上迭代一次就更快更容易。
  • 删除调试代码
  • 使用两个变量作为当前位置。使用元组作为当前位置。