[英]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: 基本上,有两种可能的方法:
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: 那么,你有两种可能的方法:
append
method is almost certainly ordered; 任何带有append
方法的东西几乎都是有序的; and 和 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.