简体   繁体   English

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

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

Here's what I have so far: 这是我到目前为止所拥有的:

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

Is there a much better way to do this? 有没有更好的方法来做到这一点?

NB: I do mean ordered and not sorted. NB:我的意思是有序而不是排序。

Motivation: 动机:

I want to iterate over an ordered collection. 我想迭代一个有序的集合。 eg 例如

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

In this case the fact that priorities is ordered is important. 在这种情况下,优先级有序的事实很重要。 What kind of collection it is is not. 什么样的收藏不是。 I'm trying to live duck-typing here. 我想在这里打鸭子。 I have frequently been dissuaded by from type checking by Pythonistas. 我经常被Pythonistas的类型检查所劝阻。

If the collection is truly arbitrary (meaning it can be of any class whatsoever), then the answer has to be no . 如果集合真的是任意的(意味着它可以是任何类),那么答案必须是否定的

Basically, there are two possible approaches: 基本上,有两种可能的方法:

  1. know about every possible class that can be presented to your method, and whether it's ordered; 了解可以呈现给您的方法的每个可能的类,以及它是否有序;
  2. test the collection yourself by inserting into it every possible combination of keys, and seeing whether the ordering is preserved. 通过将每个可能的键组合插入其中,并查看是否保留了顺序来自己测试该集合。

The latter is clearly infeasible. 后者显然是不可行的。 The former is along the lines of what you already have, except that you have to know about every derived class such as collections.OrderedDict ; 前者与你已经拥有的一致,除了你必须知道每个派生类,如collections.OrderedDict ; checking for dict is not enough. 检查dict是不够的。

Frankly, I think the whole is_ordered check is a can of worms. 坦率地说,我认为整个is_ordered check是一种蠕虫。 Why do you want to do this anyway? 你为什么要这样做呢?

Update: In essence, you are trying to unittest the argument passed to you. 更新:实质上,您正试图对传递给您的参数进行单元测试。 Stop doing that, and unittest your own code. 停止这样做,并对您自己的代码进行单元测试。 Test your consumer (make sure it works with ordered collections), and unittest the code that calls it, to ensure it is getting the right results. 测试您的消费者(确保它与有序集合一起使用),并对调用它的代码进行单元测试,以确保它获得正确的结果。

In a statically-typed language you would simply restrict yourself to specific types. 在静态类型语言中,您只需将自己限制为特定类型。 If you really want to replicate that, simply specify the only types you accept, and test for those. 如果你真的想要复制它,只需指定你接受的唯一类型,并测试它们。 Raise an exception if anything else is passed. 如果传递任何其他内容,则引发异常。 It's not pythonic, but it reliably achieves what you want to do 它不是pythonic,但它可靠地实现了你想要做的事情


Well, you have two possible approaches: 那么,你有两种可能的方法:

  1. Anything with an append method is almost certainly ordered; 任何带有append方法的东西几乎都是有序的; and
  2. If it only has an add method, you can try adding a nonce-value, then iterating over the collection to see if the nonce appears at the end (or, perhaps at one end); 如果它只有一个add方法,你可以尝试添加一个nonce-value,然后遍历集合以查看nonce是否出现在结尾(或者,可能在一端); you could try adding a second nonce and doing it again just to be more confident. 你可以尝试添加第二个nonce并再次做它只是为了更自信。

Of course, this won't work where eg the collection is empty, or there is an ordering function that doesn't result in addition at the ends. 当然,这在集合为空的情况下不起作用,或者存在不会在末端添加的排序函数。

Probably a better solution is simply to specify that your code requires ordered collections, and only pass it ordered collections. 可能更好的解决方案只是指定您的代码需要有序集合,并且只传递有序集合。

I think that enumerating the 90% case is about as good as you're going to get (if using Python 3, replace basestring with str). 我认为列举90%的情况与你将得到的一样好(如果使用Python 3,用str替换basestring)。 Probably also want to consider how you would handle generator expressions and similar ilk, too (again, if using Py3, skip the xrangor): 可能还想考虑如何处理生成器表达式和类似的同类(再次,如果使用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))

If your callers start using itertools, then you'll also need to add itertools types as returned by islice, imap, groupby. 如果你的调用者开始使用itertools,那么你还需要添加islice,imap,groupby返回的itertools类型。 But the sheer number of these special cases really starts to point to a code smell . 但这些特殊情况的绝对数量真​​正开始指向代码气味

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

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

相关问题 从顶部(或任意索引)开始查找字典的*有序*交集的有效方法? - Efficient way to find *ordered* intersection of dictionaries starting at top (or an arbitrary index)? Python中有序集合的交集 - Intersection of ordered collection in python 在给定无序输入和相应 ID 的情况下设置元素的 Numpy-thonic 方法 - Numpy-thonic way to set elements given un-ordered input and corresponding IDs 给定两组角索引坐标,有没有办法提取任意多维 Python 数组的实心框切片? - Is there a way to extract a solid box slice of an arbitrary multidimensional Python array given two sets of corner index coordinates? 保持按属性排序的对象集合 - Keeping collection of objects ordered by an attribute 重塑任意集合numpy数组 - reshaping an arbitrary collection numpy arrays Python-判断给定字符串中是否只有1个字符重复的最有效方法是什么? - Python- What is the most efficient way to tell if a given string has only 1 character duplicated in it? Python:字典的有序集合的子类或元类 - Python: subclass or metaclass for an ordered collection of dictionaries 如何检查是否订购了 Python 集合? - How can I check if a Python collection is ordered? 使用给定的有序数据集启动二维数组 - initiate 2d array with given ordered datasets
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM