繁体   English   中英

鉴于任意收集,有没有办法告诉它是否被订购?

[英]Given an arbitrary collection, is there a way to tell if it is ordered?

这是我到目前为止所拥有的:

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")

有没有更好的方法来做到这一点?

NB:我的意思是有序而不是排序。

动机:

我想迭代一个有序的集合。 例如

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

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

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

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

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

后者显然是不可行的。 前者与你已经拥有的一致,除了你必须知道每个派生类,如collections.OrderedDict ; 检查dict是不够的。

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

更新:实质上,您正试图对传递给您的参数进行单元测试。 停止这样做,并对您自己的代码进行单元测试。 测试您的消费者(确保它与有序集合一起使用),并对调用它的代码进行单元测试,以确保它获得正确的结果。

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


那么,你有两种可能的方法:

  1. 任何带有append方法的东西几乎都是有序的;
  2. 如果它只有一个add方法,你可以尝试添加一个nonce-value,然后遍历集合以查看nonce是否出现在结尾(或者,可能在一端); 你可以尝试添加第二个nonce并再次做它只是为了更自信。

当然,这在集合为空的情况下不起作用,或者存在不会在末端添加的排序函数。

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

我认为列举90%的情况与你将得到的一样好(如果使用Python 3,用str替换basestring)。 可能还想考虑如何处理生成器表达式和类似的同类(再次,如果使用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类型。 但这些特殊情况的绝对数量真​​正开始指向代码气味

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM