[英]How can I tell if a structure in Python has order?
I'm writing a set of test cases for users new to Python. 我正在为刚接触Python的用户编写一组测试用例。 One of the problems I've noticed with my tests is that its possible to get false positives. 我在测试中注意到的一个问题是可能会出现误报。 They may have gotten lucky and happened to give every element in the correct order, however they really should be using a structure that is ordered. 他们可能已经幸运并碰巧以正确的顺序给出每个元素,但他们确实应该使用有序的结构。
So far this is the best solution I could come up with. 到目前为止,这是我能想出的最佳解决方案。
self.assertTrue(isinstance(result, Sequence) or
isinstance(result, GeneratorType) or
callable(getattr(result, '__reversed__', False)))
However, I don't feel confident GeneratorType
is really ordered, or that this test is comprehensive. 但是,我不确定GeneratorType
是否真的有序,或者这个测试是全面的。 I feel like there should be a better way to test for this. 我觉得应该有更好的方法来测试这个。 How do I test that a structure has order? 如何测试结构是否有订单?
I think, it is very interesting guestion. 我想,这是非常有趣的猜测。 There is no way in pure python (without utility code) to check if collection is ordered. 纯python(没有实用程序代码)无法检查集合是否已订购。
Let's go sequentially =) 让我们顺序=)
To check Sequence
or GeneratorType
you can use collections.Iterable
type. 要检查Sequence
或GeneratorType
您可以使用collections.Iterable
类型。
>>>
>>> import collections
>>>
>>> result = [1,2,3,4,-1]
>>> isinstance(result, collections.Iterable)
True
>>>
>>> def generator_func(arg=10):
... for i in xrange(arg):
... yield i
...
>>>
>>> generator_func()
<generator object generator_func at 0x7f667c50f190>
>>>
>>> result = generator_func()
>>> isinstance(result, collections.Iterable)
True
But: 但:
>>>
>>> result = {1,2,3,4,-1}
>>> isinstance(result, collections.Iterable)
True
>>>
It is bad case for you. 这对你来说很糟糕。 Because: 因为:
>>> x = {1,2,3,-1}
>>> x
set([1, 2, 3, -1])
>>> [_ for _ in x]
[1, 2, 3, -1]
>>> x = {1,2,3,0}
>>> x
set([0, 1, 2, 3])
>>> [_ for _ in x]
[0, 1, 2, 3]
>>> import collections
>>> isinstance(x, collections.Iterable)
True
>>>
Of course for this case you should use a collections.Sequence only. 当然,对于这种情况,您应该使用集合。仅限序列。
>>> result = {1,2,3,4,-1}
>>> isinstance(result, collections.Sequence)
False
>>> isinstance({1:2, 3:3}, collections.Sequence)
False
>>>
But: 但:
>>> result = generator_func()
>>> isinstance(result, collections.Sequence)
False
>>>
Thus, I think that an idea to check Sequence or GeneratorType
is nice. 因此,我认为检查Sequence or GeneratorType
的想法很好。 Check this link: 检查此链接:
So: 所以:
>>> result = generator_func()
>>> isinstance(result, (collections.Sequence, collections.Iterator))
True
>>> result = [1,2,3,4,5]
>>> isinstance(result, (collections.Sequence, collections.Iterator))
True
>>> result = (1,2,3,4,5)
>>> isinstance(result, (collections.Sequence, collections.Iterator))
True
>>> result = {1,2,3,4,5}
>>> isinstance(result, (collections.Sequence, collections.Iterator))
False
>>> result = {1:1,2:2,3:3,4:4,5:5}
>>> isinstance(result, (collections.Sequence, collections.Iterator))
False
>>>
Аbout order. А关于订单。
If you are not sure about order of items, I think you should check them explicitly. 如果你不确定物品的顺序,我认为你应该明确检查它们。
«Explicit is better than implicit.» «明确比隐含更好。»
>>>
>>> def order_check(result, order_rule = cmp_rule):
... for item, next_item in zip(result, result[1:]):
... if not order_rule(item, next_item):
... return False
... return True
...
>>> def cmp_rule(item, next_item):
... if item < next_item:
... return True
... return False
...
>>>
>>> result = [1,2,3,4,5]
>>> order_check(result)
True
>>> result = [1,2,3,4,5,-1]
>>> order_check(result)
False
>>>
But, honestly, generators guarantee that the order would be the same as you generate in it. 但是,老实说,生成器保证订单与您在其中生成的订单相同。
You haven't entirely described what you mean by the property of having "order"; 您还没有完全描述您拥有“订单”的财产的含义; your "callable" is a good idea. 你的“可赎回”是个好主意。 I suggest that you read through the "dunder" (double underscore) methods to see whether one of them matches the definition you want. 我建议您通读“dunder”(双下划线)方法来查看其中一个是否符合您想要的定义。 From what you've given us, I strongly suspect that __getitem__
is what you want. 根据你给我们的内容,我强烈怀疑__getitem__
是你想要的。 There is also the "ask forgiveness" method of setting a try-except block on the structure: 还有“请求宽恕”方法在结构上设置try-except块:
try:
dummy = (_ for _ in result)
has_order = True
except:
has_order = False
return has_order
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.