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

K E*_*gle 10 python testing

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

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

self.assertTrue(isinstance(result, Sequence) or
                isinstance(result, GeneratorType) or
                callable(getattr(result, '__reversed__', False)))
Run Code Online (Sandbox Code Playgroud)

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

Ili*_*tin 3

我认为,这是一个非常有趣的问题。\n在纯Python(没有实用程序代码)中没有办法检查集合是否有序。

\n\n

我们按顺序来吧 =)

\n\n

要检查SequenceGeneratorType\n您可以使用collections.Iterable类型。

\n\n\n\n
>>>\n>>> import collections\n>>>\n>>> result = [1,2,3,4,-1]\n>>> isinstance(result, collections.Iterable)\nTrue\n>>>\n>>> def generator_func(arg=10):\n...     for i in xrange(arg):\n...         yield i\n...\n>>>\n>>> generator_func()\n<generator object generator_func at 0x7f667c50f190>\n>>>\n>>> result = generator_func()\n>>> isinstance(result, collections.Iterable)\nTrue\n
Run Code Online (Sandbox Code Playgroud)\n\n

但:

\n\n
>>>\n>>> result = {1,2,3,4,-1}\n>>> isinstance(result, collections.Iterable)\nTrue\n>>>\n
Run Code Online (Sandbox Code Playgroud)\n\n

这对你来说是个糟糕的情况。\n因为:

\n\n
>>> x = {1,2,3,-1}\n>>> x\nset([1, 2, 3, -1])\n>>> [_ for _ in x]\n[1, 2, 3, -1]\n>>> x = {1,2,3,0}\n>>> x\nset([0, 1, 2, 3])\n>>> [_ for _ in x]\n[0, 1, 2, 3]\n>>> import collections\n>>> isinstance(x, collections.Iterable)\nTrue\n>>>\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,对于这种情况,您应该仅使用 collections.Sequence 。

\n\n
>>> result = {1,2,3,4,-1}\n>>> isinstance(result, collections.Sequence)\nFalse\n>>> isinstance({1:2, 3:3}, collections.Sequence)\nFalse\n>>>\n
Run Code Online (Sandbox Code Playgroud)\n\n

但:

\n\n
>>> result = generator_func()\n>>> isinstance(result, collections.Sequence)\nFalse\n>>> \n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n\n\n

所以:

\n\n
>>> result = generator_func()\n>>> isinstance(result, (collections.Sequence, collections.Iterator))\nTrue\n>>> result = [1,2,3,4,5]\n>>> isinstance(result, (collections.Sequence, collections.Iterator))\nTrue\n>>> result = (1,2,3,4,5)\n>>> isinstance(result, (collections.Sequence, collections.Iterator))\nTrue\n>>> result = {1,2,3,4,5}\n>>> isinstance(result, (collections.Sequence, collections.Iterator))\nFalse\n>>> result = {1:1,2:2,3:3,4:4,5:5}\n>>> isinstance(result, (collections.Sequence, collections.Iterator))\nFalse\n>>> \n
Run Code Online (Sandbox Code Playgroud)\n\n

\xd0\x90大约订单。

\n\n

如果您不确定项目的顺序,\n我认为您应该明确检查它们。

\n\n
\n

\xc2\xab 显式优于隐式。\xc2\xbb

\n
\n\n
>>>\n>>> def order_check(result, order_rule = cmp_rule):\n...     for item, next_item in zip(result, result[1:]):\n...         if not order_rule(item, next_item):\n...             return False\n...     return True\n...\n>>> def cmp_rule(item, next_item):\n...     if item < next_item:\n...         return True\n...     return False\n...\n>>>\n>>> result = [1,2,3,4,5]\n>>> order_check(result)\nTrue\n>>> result = [1,2,3,4,5,-1]\n>>> order_check(result)\nFalse\n>>>\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,老实说,生成器保证\n顺序将与您在其中生成的顺序相同。

\n