【问题标题】:Is there a data type/structure that can: hold a list of numbers, is hashable, unordered, and allows duplicates是否有一种数据类型/结构可以:保存数字列表、可散列、无序并允许重复
【发布时间】:2019-10-25 20:17:12
【问题描述】:

正在查看此 Difference between tuples and frozensets in Python 并引导我针对我的问题提出这个问题

基本上我想要一个像元组但无序的数据类型,或者像frozenset但允许重复的数据类型(我意识到根据定义集不能这样做,但我只是在解释我想要的):可散列,无序,允许重复.

我正在尝试制作一组​​此类数据来检查不同的值,例如 (1,2,3) 应该被视为与 (1,3,2) 相同。我知道一种解决方案是使用列表,对其进行排序,然后将其设为元组,但我必须多次这样做,而且元组长度可能很长,所以如果可能的话,我宁愿不必每次都进行排序。

编辑:

问题略有改变。现在我有一个元组列表,例如: list_tuple = [(2, 2, 2), (2, 2, 2), (2, 1, 1)]

虽然问题没有太大变化,元组有一个重要的顺序,但元组的顺序没有。例如,这与前一个相同: [(2, 2, 2), (2, 1, 1),(2, 2, 2)] 我会得到很多我想添加到集合中的这些,这样我就可以计算不同的元组列表的数量。所以真的我有同样的问题,顺序无关紧要并且允许重复,除了我们正在处理元组而不是整数。

我想我应该对元组列表进行排序,然后使列表成为一个元组,它可以进入集合并正常工作。我知道我说过我不想排序,但我没有看到其他方式。

谢谢

【问题讨论】:

  • 你可以在这里查看答案:stackoverflow.com/questions/55267781/…
  • 所以基本上你想要一个不可变的collections.Counter?
  • @Aran-Fey:听起来更像是multiset,AFAIK 不在任何标准模块(或内置模块)中。
  • 计数器基本上是一个多重集;它只是不显式存储每个对象,而是一个计数,指示您需要在元素的迭代中包含对象的次数。 {{'a', 'a', 'b'}}(构成多步语法)和Counter({'a': 2, 'b': 1}) 之间几乎没有什么有意义的区别。
  • @chepner:我想是的。 FWIW,pypi 上有一个 multiset 模块。

标签: python python-3.x data-structures set hashable


【解决方案1】:

根据您的用例,您可以将Counter 对象包装在MappingProxyType 中,从而为您提供对底层Counter 的只读访问权限。

>>> from collections import Counter
>>> from types import MappingProxyType
>>> d1 = MappingProxyType(Counter("aab"))
>>> d2 = MappingProxyType(Counter("aba"))
>>> d1 == d2
True

据我所知,没有办法获得对底层 Counter 对象的引用,以便您可以修改它们。

您只需要做一些工作来迭代重复项;幸运的是,itertools 模块完成了大部分繁重的工作。

>>> from itertools import chain, startup, repeat
>>> list(chain.from_iterable(starmap(repeat, d1.items())))
['a', 'a', 'b']
>>> list(chain.from_iterable(starmap(repeat, d2.items())))
['a', 'a', 'b']

【讨论】:

  • 感谢您的评论,检查我的编辑。计数器可以用来表示我的数据,但是我需要将它添加到一个集合中,因为我想计算不同的元组列表的数量。但据我所知,计数器不是可散列的,而且要么是 MappingProxyType。我一开始说我不想排序,但也许这是唯一的选择,对元组列表进行排序,使元组列表成为元组的元组,然后将其添加到集合中。这将涵盖我的情况,但如果您认为有更好的方法来做到这一点,请告诉我
  • 我不明白为什么你需要 CounterMappingProxyType 是可散列的。 MappingProxyType(Counter([(2,2,2), (2,2,1), (2,2,2)])).
  • 我可能错过了 MappingProxyType 为我做的事情,但 Counter([(2,2,2), (2,2,1), (2,2,2)]) 只是一个例如,我会说一堆这些,我需要区分。将它们添加到一组似乎是最有效的方法,而不是我必须检查它是否在那里的列表。因为 iirc 就像列表的 O(n) 但集合的 O(1) 因此我希望它是可散列的。对不起,如果我只是不明白
  • 好的,我明白了,你改变的问题现在完全不同了。我虽然你是从(比如)ints 的多重集到元组的多重集,但是你正在从元组的多重集到元组的多重集。
  • 是的。我可以对列表中的各个元组组进行排序,然后将其设为一个元组,然后我就可以使用 set() ... 无论如何,这样做可能过于复杂。不想列出我正在解决的问题,因为我想尝试自己解决,但基本上是尝试根据其形状找到独特的子树。所以我试图以某种方式将树的形状变成我能遇到的最简单的表示形式。 (2,2,2), (2,2,1), (2,2,2) 表示根有 2 个孩子,每个元组是从它所代表的路径出来的路径 # of children
猜你喜欢
  • 1970-01-01
  • 2010-10-29
  • 2010-10-22
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-07
相关资源
最近更新 更多