为什么排序列表检测在这种情况下不起作用?
Why sorted list detection does not work in this situation?
我的目标是让 python 代码能够检测列表是否已排序。
我想明白为什么下面的代码 return True
而不是我预期的猜测 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"
备注:
- 我在 iPython 0.10
中使用 python 2.6.4
- 我使用了非常大的列表,所以我宁愿避免
l == l.sort()
类型的解决方案
为了理解这一点,我已经阅读(并测试)了以下主要两个信息 post:
编辑:
好的,显然问题仅出现在 iPython 中,而不是仅在使用 python 命令行时出现!
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
我能够在我的机器上重现类似的问题。然而,经过挖掘,发现all
函数不是内置函数而是来自numpy(all.__module__ == 'numpy.core.fromnumeric'
).
问题是您创建的是生成器而不是列表。例如:
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
只需将 [...]
添加到您的表达式中:
all([l[i] <= l[i+1] for i in xrange(len(l)-1)])
# False
如果您确实需要创建一个列表,更有效的解决方案是执行一个简单的 for 循环:
for i in xrange(len(l)-1):
if l[i] > l[i+1]:
result = False
break
else:
result = True
如果像我一样,你覆盖了内置的 all
功能,你可以 del all
来恢复它。在那之后,你应该有 all.__module__ == '__builtin__'
。如果还是不行,那就all = __builtin__.all
您在问题中提供的代码工作正常:
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
我们用 range
代替 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 与 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
最后看来 iPython 0.10 中的可行解决方案是:
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
编辑:
或者更好:使用已接受答案中提供的循环!
我的目标是让 python 代码能够检测列表是否已排序。
我想明白为什么下面的代码 return True
而不是我预期的猜测 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"
备注:
- 我在 iPython 0.10 中使用 python 2.6.4
- 我使用了非常大的列表,所以我宁愿避免
l == l.sort()
类型的解决方案
为了理解这一点,我已经阅读(并测试)了以下主要两个信息 post:
编辑: 好的,显然问题仅出现在 iPython 中,而不是仅在使用 python 命令行时出现!
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
我能够在我的机器上重现类似的问题。然而,经过挖掘,发现all
函数不是内置函数而是来自numpy(all.__module__ == 'numpy.core.fromnumeric'
).
问题是您创建的是生成器而不是列表。例如:
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
只需将 [...]
添加到您的表达式中:
all([l[i] <= l[i+1] for i in xrange(len(l)-1)])
# False
如果您确实需要创建一个列表,更有效的解决方案是执行一个简单的 for 循环:
for i in xrange(len(l)-1):
if l[i] > l[i+1]:
result = False
break
else:
result = True
如果像我一样,你覆盖了内置的 all
功能,你可以 del all
来恢复它。在那之后,你应该有 all.__module__ == '__builtin__'
。如果还是不行,那就all = __builtin__.all
您在问题中提供的代码工作正常:
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
我们用 range
代替 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 与 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
最后看来 iPython 0.10 中的可行解决方案是:
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
编辑: 或者更好:使用已接受答案中提供的循环!