random.shuffle 如何导致 KeyError?

Mar*_*oma 5 python random shuffle python-2.7 keyerror

我刚刚收到错误:

Traceback (most recent call last):
  File "./download_documents.py", line 153, in <module>
    paragraphs, used_pages = find_pages(lang, to_extract)
  File "./download_documents.py", line 67, in find_pages
    random.shuffle(page_titles_queue)
  File "/usr/lib/python2.7/random.py", line 291, in shuffle
    x[i], x[j] = x[j], x[i]
KeyError: 1
Run Code Online (Sandbox Code Playgroud)

这让我很困惑。

  1. random.shuffle 似乎适用于零元素列表和单元素列表。
  2. page_titles_queue 是元组列表。
  3. 之后的两行random.shuffle(page_titles_queue),有page_titles_queue.pop(),但这不应该影响洗牌。对?

那么 KeyError 的可能原因是什么?

Python 2.7.12在 Ubuntu 16.04 上使用。

MSe*_*ert 5

random.shuffle只是交换物品,发生异常的行清楚地表明了这一点:

x[i], x[j] = x[j], x[i]
Run Code Online (Sandbox Code Playgroud)

在哪里x是传入的“序列”。在这种情况下,ij将是范围内的值range(0, len(x)),如果其中任何一个ij不存在于“序列”中,它将抛出一个Exception. 在你的情况下,它很可能会抛出一个KeyError

>>> import random
>>> d = {i: i for i in range(7, 10)}
>>> random.shuffle(d)
KeyError: 3
Run Code Online (Sandbox Code Playgroud)

然而,它的工作原理是交换值,以防字典恰好包含组成的键range(0, len(x))

>>> d = {i: i for i in range(10)}
>>> random.shuffle(d)
>>> d
{0: 7, 1: 9, 2: 3, 3: 4, 4: 0, 5: 2, 6: 1, 7: 6, 8: 8, 9: 5}
Run Code Online (Sandbox Code Playgroud)

如果一个或多个键丢失,它可能会起作用,也可能会抛出一个Exception. 这取决于将抽取哪些随机数:

d = {i: i for i in range(1, 10)}
random.shuffle(d)   # works sometimes, but sometimes it throws the KeyError
Run Code Online (Sandbox Code Playgroud)