在循环中添加和删除deque中的项目时出现意外行为

时间:2013-08-15 21:02:38

标签: python loops deque

我遇到的问题是函数arrangeNodes()。 它似乎为我作为争论传递给它的词典增加了无关的价值。 dict'stops'通过使用'foo'中的值来填充,这些值在一定范围内。我已经在下面展示了foo中任何时候的最大值都是3.因为函数在dict中的键上迭代一次,所以每个键只在第一个for循环和第二个for循环中使用一次,与密钥关联的集合最多只能包含3个值。

然而,在执行该函数后,我突然在dict

中的每个集合中有超过3个值
#!/usr/bin python
from collections import deque

d_min = int(raw_input())
d_max = int(raw_input())

def arrangeNodes(keys, stops):
    foo = deque()
    for r in keys:
        k = r + d_max
        while len(foo) and k < foo[0]: foo.popleft()
        for num in foo:
            if d_min <= num - r <= d_max: stops[r].add(num)
            else: break
        foo.append(r)
    return  


ans = 0
motels = {}.fromkeys([7000, 6010, 5990, 5030, 4970, 4060, 3930, 3060, 2940, 2030, 1970, 1010, 990, 0], set())
motels.update({}.fromkeys((int(raw_input()) for _ in xrange(int(raw_input()))), set()))
print motels #All sets in this dict are empty before the function call
arrangeNodes(sorted(motels.iterkeys(), reverse=True), motels)
for v in motels:
    print v, motels[v]

样本输入:970,1040,0

使用此输入,容器'foo'的最大长度不应超过3.以下是函数中每次迭代的foo值:

deque([])
deque([7000])
deque([7000, 6010])
deque([6010, 5990])
deque([6010, 5990, 5030])
deque([5030, 4970])
deque([4970, 4060])
deque([4060, 3930])
deque([3930, 3060])
deque([3060, 2940])
deque([2940, 2030])
deque([2030, 1970])
deque([2030, 1970, 1010])
deque([1010, 990])

因此,dict'motels'在其包含的集合中不应超过3个值。 但是每当我运行这个程序时,在执行函数后打印汽车旅馆时会得到以下输出:

0 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
5990 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
5030 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
2940 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
4970 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
1010 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
2030 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
1970 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
3060 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
7000 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
6010 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
4060 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
3930 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])
990 set([5990, 5030, 2940, 4970, 1010, 2030, 1970, 3060, 7000, 6010, 4060, 3930, 990])

我不明白为什么会这样。有人可以解释一下吗?

1 个答案:

答案 0 :(得分:2)

我发现您的代码有点难以阅读,因为您不清楚自己想要做什么。但是,我假设您不希望dict items所有set实例都指向相同的motels = {}.fromkeys([7000, 6010, 5990, 5030, 4970, 4060, 3930, 3060, 2940, 2030, 1970, 1010, 990, 0], set()) 实例,这是

之后的情况
>>> motels[7000].add(1)
>>> print motels[0]
    set([1])

如果您这样做:

set

因为所有键都指向同一个项目。在使用用户提供的信息更新dict之后,将会有另一个0实例,但这与motels = dict([(i, set()) for i in [7000, 6010, 5990, 5030, 4970, 4060, 3930, 3060, 2940, 2030, 1970, 1010, 990, 0]]) 的示例输入无关。试试这个

motels

初始化您的set。这将为每个密钥创建一个for i in xrange(int(raw_input())): motels[int(raw_input())] = set() 实例。 然后做

motels

用于更新{{1}}(在我看来也更具可读性)。