【问题标题】:Given an arbitrary collection, is there a way to tell if it is ordered?给定一个任意集合,有没有办法判断它是否是有序的?
【发布时间】:2012-05-11 19:47:54
【问题描述】:

这是我目前所拥有的:

def is_ordered(collection):
    if isinstance(collection, set):
        return False
    if isinstance(collection, list):
        return True
    if isinstance(collection, dict):
        return False

    raise Exception("unknown collection")

有更好的方法吗?

注意:我的意思是有序且排序。

动机:

我想遍历一个有序集合。例如

def most_important(priorities):
    for p in priorities:
        print p

在这种情况下,优先级排序这一事实很重要。不是什么收藏品。我想在这里过着打鸭子的生活。我经常被 Pythonistas 的类型检查所劝阻。

【问题讨论】:

  • 对于collections.OrderedDict 的实例,您的代码已经失败
  • 还有我认为的其他各种。关键是,我是否需要测试每个可能的集合,还是有更强大的方法来做到这一点?
  • 只需对其进行迭代,并确保调用者传递的是有序集合。

标签: python collections python-2.7


【解决方案1】:

更新:本质上,您正在尝试对传递给您的参数进行单元测试。停止这样做,然后对您自己的代码进行单元测试。测试您的消费者(确保它适用于有序集合),并对调用它的代码进行单元测试,以确保它得到正确的结果。

在静态类型语言中,您只需将自己限制为特定类型。如果您真的想复制它,只需指定您接受的唯一类型,然后测试它们。如果传递了其他任何内容,则引发异常。它不是pythonic,但它可靠地实现了您想要做的事情


嗯,你有两种可能的方法:

  1. 任何带有append 方法的东西几乎肯定是有序的;和
  2. 如果它只有一个add 方法,您可以尝试添加一个nonce 值,然后遍历集合以查看nonce 是否出现在最后(或者,可能出现在一端);您可以尝试添加第二个 nonce,然后再做一次,这样会更有信心。

当然,这在例如集合是空的,或者有一个排序函数不会在末尾产生加法。

可能更好的解决方案是简单地指定您的代码需要有序集合,并且只传递有序集合。

【讨论】:

    【解决方案2】:

    我认为枚举 90% 的情况与您将获得的一样好(如果使用 Python 3,请将 basestring 替换为 str)。可能还想考虑如何处理生成器表达式和类似的东西(同样,如果使用 Py3,请跳过 xrangor):

    generator = type((i for i in xrange(0)))
    enumerator = type(enumerate(range(0)))
    xrangor = type(xrange(0))
    is_ordered = lambda seq : isinstance(seq,(tuple, list, collections.OrderedDict,
                                              basestring, generator, enumerator, xrangor))
    

    如果您的调用者开始使用 itertools,那么您还需要添加由 islice、imap、groupby 返回的 itertools 类型。但是这些特殊情况的绝对数量确实开始指向code smell

    【讨论】:

      【解决方案3】:

      如果集合真的是任意的(意味着它可以是任何类别),那么答案必须是

      基本上,有两种可能的方法:

      1. 了解可以呈现给您的方法的每个可能的类,以及它是否已排序;
      2. 通过将所有可能的键组合插入其中来自行测试集合,并查看是否保留了顺序。

      后者显然是不可行的。前者与您已经拥有的基本相同,只是您必须了解每个派生类,例如collections.OrderedDict;检查dict 是不够的。

      坦率地说,我认为整个is_ordered 检查是一罐蠕虫。你为什么要这样做?

      【讨论】:

      • 我可以设置一个可能有用的标准限制吗?还是我应该像以前那样进行班级检查?
      • @cammil 为什么不直接使用人类语言(例如英语)指定只必须传递有序集合,并检查您的调用代码以确保您这样做?
      • @cammil:TBH,我真的不明白用例。
      【解决方案4】:

      如果列表没有排序怎么办,例如[1,3,2]?

      【讨论】:

      • [1,3,2] 有序的。未排序。
      • 我不知道你说的“订购”是什么意思?但我同意 aix 写的 - 真的你不能。任何人都可以实现一个有序的“dict”,例如集合库中有一个 OrderedDict 类。
      • @uhzzre:取一个像"hello"这样的字符串。它是有序的(= 字符的顺序很重要)。不过它没有排序,否则它会是"ehllo"
      猜你喜欢
      • 2023-01-11
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 2020-08-07
      相关资源
      最近更新 更多