Why sorted list detection does not work in this situation?

て烟熏妆下的殇ゞ 提交于 2019-12-14 02:50:22

问题


My goal is to have python code allowing to detect if a list is sorted or not.

I would like to understand why the following code return True instead of my expected guess False

l = [1, 2, 3, 4, 1, 6, 7, 8, 7]
all(l[i] <= l[i+1] for i in xrange(len(l)-1)) # return "True"

Notes:

  • I'm using python 2.6.4 inside iPython 0.10
  • I use very huge list so I'd prefer to avoid solution of type l == l.sort()

In the way to understand this I already read (and test) info from the main two following post:

  • https://stackoverflow.com/a/3755251/4716013
  • https://stackoverflow.com/a/4710776/4716013

EDIT: OK apparently the problem appear inside iPython ONLY, not when using only python command line!

iPython 0.10

In [93]: l = [1, 2, 3, 4, 1, 6, 7, 8, 7]

In [94]: all(l[i] <= l[i+1] for i in xrange(len(l)-1))
Out[94]: True

python 2.6.4

>>> l = [1, 2, 3, 4, 1, 6, 7, 8, 7]
>>> all(l[i] <= l[i+1] for i in xrange(len(l)-1))
False

回答1:


I was able to reproduce a similar problem on my machine. However, after digging, it occurred that the all function was not the built-in function but came from numpy (all.__module__ == 'numpy.core.fromnumeric').

The problem is that you are creating a generator rather than a list. For example:

all(x>5 for x in xrange(3))
# <generator object <genexpr> at 0x1153bf7d0>

all([x>5 for x in xrange(3)])
# False

if all(x>5 for x in xrange(3)):
   print True
else:
   print False
# prints True

if all([x>5 for x in xrange(3)]):
   print True
else:
   print False
# prints False

Simply add [...] to your expression:

all([l[i] <= l[i+1] for i in xrange(len(l)-1)])
# False

If it is the case that you need to create a list, a more efficient solution would be to do a simple for loop:

for i in xrange(len(l)-1):
    if l[i] > l[i+1]:
        result = False
        break
else:
    result = True

If like me, you overrode the built-in all function, you can do del all to recover it. After that, you should have all.__module__ == '__builtin__'. If that's still not the case, just do all = __builtin__.all




回答2:


The code you've presented in the question works fine:

Python 2.7

>>> l = [1, 2, 3, 4, 1, 6, 7, 8, 7]
>>> all(l[i] <= l[i+1] for i in xrange(len(l)-1))
False

Python 3.4

We substitute range for xrange...

>>> l = [1, 2, 3, 4, 1, 6, 7, 8, 7]
>>> all(l[i] <= l[i+1] for i in range(len(l)-1))
False

IPython 3.0.0 with Python 2.7.6

In [1]: l = [1, 2, 3, 4, 1, 6, 7, 8, 7]

In [2]: all(l[i] <= l[i+1] for i in xrange(len(l)-1))
Out[2]: False



回答3:


Finally it appear that a working solution in iPython 0.10 would be:

In [93]: l = [1, 2, 3, 4, 1, 6, 7, 8, 7]
In [100]: all([l[i] <= l[i+1] for i in xrange(len(l)-1)])
Out[100]: False

EDIT: Or better: use a loop as presented in the accepted answer!



来源:https://stackoverflow.com/questions/30326927/why-sorted-list-detection-does-not-work-in-this-situation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!