【问题标题】:Sorting a list of python sets by value按值对 python 集列表进行排序
【发布时间】:2018-08-11 23:47:11
【问题描述】:

frozenset 文档说:

frozenset 类型是不可变的和可散列的——它的内容在创建后不能更改;因此,它可以用作字典键或另一个集合的元素。

但是,python 集的文档说:

由于集合只定义部分排序(子集关系),list.sort() 方法的输出对于集合列表是未定义的。

这让我问:为什么会这样?而且,如果我想按集合内容对集合列表进行排序,我该怎么做?我知道扩展 intbitset: https://pypi.python.org/pypi/intbitset/2.3.0 具有返回表示设置内容的位序列的功能。 python 集有可比性吗?

【问题讨论】:

  • 请提供您不能做的代码示例,然后我们可以提供如何做的代码示例。
  • 好的,在某些情况下我理解这个请求。但是我到底需要一个代码示例在这里。这个问题有什么令人困惑的代码示例可以解决?我说得很具体。

标签: python sorting hashmap set frozenset


【解决方案1】:

元组、列表、字符串等具有自然的字典顺序并且可以排序,因为您始终可以比较给定集合的两个元素。也就是说,a < bb < aa == b

两个集合之间的自然比较是让a <= b 意味着ab 的子集,这就是表达式a <= b 在Python 中的实际作用。文档中“部分排序”的含义是并非所有集合都具有可比性。以以下集合为例:

a = {1, 2, 3}
b = {4, 5, 6}

ab 的子集吗?不是。ba 的子集吗?不,他们是平等的吗?不。如果你根本无法比较它们,你显然无法对它们进行排序。

您可以对集合进行排序的唯一方法是,如果您的比较函数实际上可以比较任意两个元素(total order)。这意味着您仍然可以使用上述子集关系对集合进行排序,但您必须确保所有集合都是可比较的(例如[{1}, {1, 2, 4}, {1, 2}])。

做你想做的最简单的方法是将每个单独的集合转换成你真正可以比较的东西。基本上,你为一些简单的函数ff(a) <= f(b)<= 很明显)。这是通过 key 关键字参数完成的:

In [10]: def f(some_set):
   ...       return max(some_set)
   ...

In [11]: sorted([{1, 2, 3, 999}, {4, 5, 6}, {7, 8, 9}], key=f)
Out[11]: [{4, 5, 6}, {7, 8, 9}, {1, 2, 3, 999}]

您正在对[f(set1), f(set2), f(set3)] 进行排序并将结果排序应用于[set1, set2, set3]

【讨论】:

    【解决方案2】:

    举个例子:假设您想按每个集合的“第一个元素”对集合列表进行排序。问题是 Python 集或冻结集没有“第一个元素”。他们没有自己的秩序感。集合是没有重复元素的无序集合。

    此外,list.sort() 对列表进行就地排序,using only the < operator between items

    如果你只使用a.sort() 而不传递任何key 参数,那么说set_a < set_b(或set_a.__lt__(set_b))是不足的。不足,我的意思是 set_a.__lt__(set_b) 是一个 subset 运算符。 (ab 的子集吗?)。正如@Blender 提到的并在您的问题中引用的那样,这提供了部分排序而不是全部排序,这不足以定义任何序列包含集合。

    来自文档:

    set < other: 测试该集合是否是其他集合的真子集,即 是,set <= otherset != other

    可以key 传递给sort(),它只是不能指代与内部集合的“排序”有关的任何事情,因为请记住——没有。

    >>> a = {2, 3, 1}
    >>> b = {6, 9, 0, 1}
    >>> c = {0}
    >>> i = [b, a, c]
    >>> i.sort(key=len)
    >>> i
    [{0}, {1, 2, 3}, {0, 9, 6, 1}]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      相关资源
      最近更新 更多