【问题标题】:Use pop method on set to drop items always drops the same items在 set 上使用 pop 方法来丢弃项目总是丢弃相同的项目
【发布时间】:2020-05-03 12:17:31
【问题描述】:
x = [1, 2, 3, 3, 4, 4]
y = set(x)

print(y)

y.pop()
y.pop()

print(y)

这是我的示例代码。在我阅读的文档中,集合总是丢弃随机项目,但我的代码总是返回:

{1, 2, 3, 4}
{3, 4}

我在这里做错了什么还是为什么前两个项目总是被丢弃?如果我想删除最后一个元素,是否需要将集合转换为列表,然后再转换回集合?

【问题讨论】:

  • 如果你不知道 set 的内部存储是如何构成的,它就不是随机的。
  • 看起来是有序的,因为 int 值是如何散列的。尝试先将x 设置为str 值列表。
  • 唯一的结论似乎是:我们可以在不弹出的情况下预测弹出的项目,因为它始终是字符串表示中的第一项。

标签: python set


【解决方案1】:

发生这种情况是因为您 pop 始终来自同一个 set。集合没有顺序,它是实现细节,它的项目在内存中究竟是如何布局的。通常,为每个项目计算一个散列函数,该函数说明哪个元素先出现。所以它不是“随机的”,因为你每次运行都会得到不同的元素,它是“随机的”,就像“任意”的意思一样,你不能依赖明显的顺序。

而且,顺便说一句。在 CPython 3.7 中,dict 现在是 ordered(但不是 set)。

【讨论】:

  • set 未排序。
  • 抱歉,我好像说错了,dict 是有序的,没有设置。请查看编辑。
【解决方案2】:

当文档说它是“随机的”时,这意味着您不应该期待任何东西,除非它会丢弃一个元素。这并不一定意味着它是一致随机的。 (从技术上讲,它是随机的,而不是人们想到随机性时所想到的一致随机)

如果您想均匀随机地删除元素,那么也许您应该考虑使用列表并在其上调用 shuffle 然后弹出元素。

random.shuffle(lst)
while lst:
  print(lst.pop())

【讨论】:

  • 文档说“任意”,我认为这是试图不暗示“随机”。
  • 这是有道理的,当用户说“在我阅读的文档中,集合总是丢弃随机项目”时,我接受了用户的话,并以此假设为依据。
猜你喜欢
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
相关资源
最近更新 更多