简体   繁体   English

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

[英]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. 要检查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

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.

相关问题 Python:如何判断我的 Python 是否具有 SSL? - Python: How can I tell if my python has SSL? 我如何告诉python我的数据结构(二进制)是什么样子,以便我可以绘制它? - How do I tell python what my data structure (that is in binary) looks like so I can plot it? 如何实现保留顺序并快速插入/删除的数据结构? - How can I implement a data structure that preserves order and has fast insertion/removal? 如何颠倒此结构的顺序? - How can I reverse the order of this structure? 我如何告诉python从列表中的电子邮件中获取最后2个单词,但是不是python定义的列表,因为它发生了变化? - How can I tell python to take the last 2 words from an email that is in a list like structure but is not a list defined by python because it changes? 如何判断是否安装了 Python setuptools? - How can I tell if Python setuptools is installed? 在 Python 3 中,如何判断 Windows 是否被锁定? - In Python 3, how can I tell if Windows is locked? 如何告诉 Django ORM 颠倒查询结果的顺序? - How can I tell the Django ORM to reverse the order of query results? 如何判断是否已在Python中调用过函数? - How do I tell whether a function has been called in Python? 我如何编程我的代码,以便它在LIFO结构的python中从上到下显示堆栈顺序 - how can I program my code so it displays a stack order from top to bottom in python for a LIFO structure
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM