繁体   English   中英

如何判断Python中的结构是否有顺序?

[英]How can I tell if a structure in Python has order?

我正在为刚接触Python的用户编写一组测试用例。 我在测试中注意到的一个问题是可能会出现误报。 他们可能已经幸运并碰巧以正确的顺序给出每个元素,但他们确实应该使用有序的结构。

到目前为止,这是我能想出的最佳解决方案。

self.assertTrue(isinstance(result, Sequence) or
                isinstance(result, GeneratorType) or
                callable(getattr(result, '__reversed__', False)))

但是,我不确定GeneratorType是否真的有序,或者这个测试是全面的。 我觉得应该有更好的方法来测试这个。 如何测试结构是否有订单?

我想,这是非常有趣的猜测。 纯python(没有实用程序代码)无法检查集合是否已订购。

让我们顺序=)

要检查SequenceGeneratorType您可以使用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

但:

>>>
>>> result = {1,2,3,4,-1}
>>> isinstance(result, collections.Iterable)
True
>>>

这对你来说很糟糕。 因为:

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

当然,对于这种情况,您应该使用集合。仅限序列。

>>> result = {1,2,3,4,-1}
>>> isinstance(result, collections.Sequence)
False
>>> isinstance({1:2, 3:3}, collections.Sequence)
False
>>>

但:

>>> result = generator_func()
>>> isinstance(result, collections.Sequence)
False
>>> 

因此,我认为检查Sequence or GeneratorType的想法很好。 检查此链接:

所以:

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

А关于订单。

如果你不确定物品的顺序,我认为你应该明确检查它们。

«明确比隐含更好。»

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

但是,老实说,生成器保证订单与您在其中生成的订单相同。

您还没有完全描述您拥有“订单”的财产的含义; 你的“可赎回”是个好主意。 我建议您通读“dunder”(双下划线)方法来查看其中一个是否符合您想要的定义。 根据你给我们的内容,我强烈怀疑__getitem__是你想要的。 还有“请求宽恕”方法在结构上设置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.

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