【问题标题】:Python: list.pop(0) gives index error while list is full [duplicate]Python:list.pop(0)在列表已满时给出索引错误[重复]
【发布时间】:2016-12-04 13:51:00
【问题描述】:

所以我试图找回 n 个商店的列表,以便它们是邻居,然后,如果有必要,是邻居的邻居。下面是用于计算此列表的代码,称为locations。商店的编号从 1 到 10(含)。

在这种情况下,每个商店有 4 个邻居。这种关系是在名为neighbours的字典中随机设置的。

import random

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

neighbours = {}

for i in shops:
    neighbours[i] = random.sample(shops, 4)
    while i in neighbours[i]:
        neighbours[i] = random.sample(shops, 4)
print (neighbours)
shop_zero = random.randrange(1,11)
locations = [shop_zero]
neighborhd = neighbours[locations[0]]
n=10
while len(locations) < n:
    if not neighborhd:
        print('if statement')
        neighborhd = neighbours[random.choice(locations)]
        print (neighborhd)
    print('while loop')
    ne = neighborhd.pop(0)
    if ne not in locations:
        locations.append(ne)
print (locations)

问题是代码有时可以工作,但它经常给我一个索引错误:

IndexError: pop from empty list

对于那些感兴趣的人,以下是邻居字典的输出:

{1: [7, 5, 4, 9], 2: [5, 6, 3, 7], 3: [10, 8, 7, 6], 4: [7, 8, 10, 2], 5: [3, 6, 1, 9], 6: [5, 1, 10, 3], 7: [3, 8, 6, 2], 8: [10, 4, 9, 7], 9: [6, 5, 3, 2], 10: [3, 5, 8, 7]}

我添加了一些打印语句以使工作示例提供更多信息。正如我之前所说,它确实经常工作,但大多数情况下它会给出索引错误。 请帮忙?

附:我意识到结果列表并不总是给我集群,而是一条从邻居到邻居的路径。这对我正在进行的项目来说很好。

【问题讨论】:

  • pop(0) 之前放一个print(neighborhd) 看看它的价值。
  • 您似乎假设neighborhd = neighbours[random.choice(locations)] 行将始终为您提供非空列表。我看不出有任何理由证明这是真的。你能澄清你的推​​理吗?
  • @A.Far 请在下面看看我的回答。谢谢
  • @MarkDickinson 我已经填写了neighbours 字典,对locations 列表进行了4 次抽样,对吧?然后我将字典的键设置为 1-10 的数字(“位置”的元素)。这不能保证每个可能的键都与非空列表相关联吗?我错过了什么吗?
  • @A.Far:是的,但是在 10 次迭代中的每一次中,您都从其中一个列表中删除了一个元素(在 ne = neighborhd.pop(0) 行中)。如果随机数出现正确,您最终会删除其中一个列表的所有四个元素,因此会出现错误。也就是说,随着 while 循环的进行,您正在 修改 neighbours 的内容。也许那不是你想做的。

标签: python python-3.x


【解决方案1】:

基本上,neighborhd = neighbours[random.choice(locations)] 有问题。它还返回空列表。所以你需要做一点改变。 if neighborhd:pop 之前只需检查它不是一个空列表。

 import random

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

neighbours = {}

for i in shops:
    neighbours[i] = random.sample(shops, 4)
    while i in neighbours[i]:
        neighbours[i] = random.sample(shops, 4)
print (neighbours)
shop_zero = random.randrange(1,11)
locations = [shop_zero]
neighborhd = neighbours[locations[0]]
n=10
while len(locations) < n:
    if not neighborhd:
        print('if statement')
        neighborhd = neighbours[random.choice(locations)]
        print (neighborhd)
    print('while loop')
    if neighborhd:
        ne = neighborhd.pop(0)
        if ne not in locations:
            locations.append(ne)
print (locations)

【讨论】:

  • neighborhdneighbours 都为空时,这会导致无限循环。尝试将其放入 for 循环 for j in range(10000): 并运行它,大约 10 分钟后它将进入无限循环。
  • @rassar,我的错误代码格式改变了代码。立即尝试。
  • @RuhulAmin 谢谢!这有效:-) 虽然我的问题是为什么会发生错误?我在while循环之前有print (neighbours),就像我自己的理智检查字典中没有值是空列表一样。它不是。但出于某种原因,有时,某些值会变成空列表。知道为什么吗?
  • @A.Far,你说,我的代码对你有用,但你接受了其他答案,没有意义
  • @RuhulAmin 是的,你的代码对我有用,谢谢。但是另一个答案提供了有关为什么我的代码不起作用的详细信息。他们提供的代码准确地展示了我的错误在哪里以及导致它的原因,这是我在这里提出问题时想知道的事情,而我选择的答案对这些问题的处理令我满意。没有难过的感觉!
【解决方案2】:

我更改了您的代码帮助调试,您可以在下面看到。如果你运行它,你会发现当抛出异常时,'neighbours' 字典有一些空列表作为一些值。这意味着“neighborhd”可能会被“neighbors”中的空列表重新填充,因此仍然是空的。

import random

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

neighbours = {}

for i in shops:
    neighbours[i] = random.sample(shops, 4)
    while i in neighbours[i]:
        neighbours[i] = random.sample(shops, 4)
print (neighbours)
shop_zero = random.randrange(1,11)
locations = [shop_zero]
neighborhd = neighbours[locations[0]]
n=10
while len(locations) < n:
    if not neighborhd:
        print('if statement')
        neighborhd = neighbours[random.choice(locations)]
        print (neighborhd)
    print('while loop')
    try:
        ne = neighborhd.pop(0)
    except IndexError:
        raise IndexError("Attempt to pop from neighborhd which has content %s, formed from neighbours which has content %s" % (neighborhd, neighbours))
    if ne not in locations:
        locations.append(ne)
print (locations)

【讨论】:

  • 啊,感谢您了解发生了什么!您知道为什么我的字典将某些值设置为空列表吗?我在 print (neighbours) 行的 while 循环之前明确检查它们是否为空(通过读出)。
  • 当您将“neighbours”中的一个列表分配给“neighborhd”时,Python 不会复制该列表,而是对其进行新的引用。您从“neighborhd”指向的列表中删除成员,但该列表仍然是“neighbors”中的值。这意味着当“neighborhd”变为空时,“neighbors”中的列表之一也是空的。
  • 阅读一下 python 以及变量是如何被引用的。还可以查找 python 副本,因为您可能想在此处使用它。
  • 是的,我现在意识到了。我正在从 C++ 迁移,这是一个美妙的,有时令人困惑的 Python 世界。我会详细了解如何处理变量,这样我就不会再遇到这种事情了。
猜你喜欢
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多