为什么'.sort()'导致Python中的列表为'None'?

时间:2012-03-19 20:08:42

标签: python list sorting

我正在尝试对int的Python列表进行排序,然后使用.pop()函数返回最高的值。我尝试过以不同的方式编写方法:

def LongestPath(T):    
    paths = [Ancestors(T,x) for x in OrdLeaves(T)]
    #^ Creating a lists of lists of ints, this part works
    result =[len(y) for y in paths ]
    #^ Creating a list of ints where each int is a length of the a list in paths
    result = result.sort()
    #^meant to sort the result
    return result.pop()
    #^meant to return the largest int in the list (the last one)

我也试过

def LongestPath(T):
    return[len(y) for y in [Ancestors(T,x) for x in OrdLeaves(T)] ].sort().pop()

在这两种情况下.sort()导致列表为None(没有.pop()函数并返回错误)。当我删除.sort()时,它工作正常,但由于列表未排序,因此不会返回最大的int

8 个答案:

答案 0 :(得分:20)

只需从

中删除作业即可
result = result.sort()

离开

result.sort()

sort方法就地工作(它修改现有列表),因此不需要进行任何分配,并返回None。将结果分配给列表名称时,您将分配None

它可以轻松(并且更有效)写成一行代码:

max(len(Ancestors(T,x)) for x in OrdLeaves(T))

max以线性时间O(n)运行,而排序为O(nlogn)。您也不需要嵌套列表推导,单个生成器表达式也可以。

答案 1 :(得分:9)

result = result.sort()

应该是这个

result.sort()

Python中的一种惯例是,变异序列的方法返回None

考虑:

>>> a_list = [3, 2, 1]
>>> print a_list.sort()
None
>>> a_list
[1, 2, 3]

>>> a_dict = {}
>>> print a_dict.__setitem__('a', 1)
None
>>> a_dict
{'a': 1}

>>> a_set = set()
>>> print a_set.add(1)
None
>>> a_set
set([1])

此设计决策背后的Python设计和历史常见问题gives the reasoning(关于列表):

  

为什么不list.sort()返回排序列表?

     

在表现很重要的情况下,制作一份清单副本   只是为了排序它会很浪费。因此,list.sort()对此进行排序   列表到位。为了提醒你这个事实,它不会回来   排序清单。这样,你就不会被意外愚弄   在需要排序副本时覆盖列表但也需要保留   未分类的版本。

     

在Python 2.4中添加了一个新的内置函数 - sorted()。   此函数从提供的iterable中创建一个新列表,对其进行排序   并将其归还。

答案 2 :(得分:4)

.sort()返回None并对列表进行排序。

答案 3 :(得分:2)

这已经得到正确回答:list.sort()返回None。原因是“命令查询分离”:

http://en.wikipedia.org/wiki/Command-query_separation

Python返回None因为每个函数都必须返回一些东西,并且约定是一个不产生任何有用值的函数应返回None

我之前从未见过你在引用的行之后发表评论的惯例,但是用一条克拉开始评论指向该行。请在他们引用的行之前加上评论。

虽然您可以使用.pop()方法,但您也可以将列表编入索引。列表中的最后一个值总是可以用-1索引,因为在Python中,负数索引“环绕”并从末尾开始向后索引。

但我们可以进一步简化。您对列表进行排序的唯一原因是您可以找到其最大值。 Python中有一个内置函数:max()

使用list.sort()需要构建整个列表。然后,您将从列表中提取一个值并将其丢弃。 max()将使用迭代器而无需分配可能大量的内存来存储列表。

此外,在Python中,社区更喜欢使用名为PEP 8的编码标准。在PEP 8中,您应该使用小写字母表示函数名称,使用下划线来分隔单词,而不是CamelCase。

http://www.python.org/dev/peps/pep-0008/

考虑到上述评论,这是我对你的功能的重写:

def longest_path(T):
    paths = [Ancestors(T,x) for x in OrdLeaves(T)]
    return max(len(path) for path in paths)

在对max()的调用中,我们有一个“生成器表达式”,用于计算列表paths中每个值的长度。 max()将从中拉出值,保持最大值,直到所有值都用完为止。

但现在很明显,我们甚至不需要paths列表。这是最终版本:

def longest_path(T):
    return max(len(Ancestors(T, x)) for x in OrdLeaves(T))

我实际上认为带有显式paths变量的版本更具可读性,但这并不可怕,如果可能存在大量路径,您可能会注意到性能提升建立并销毁paths列表。

答案 4 :(得分:1)

list.sort()不会返回列表 - 它会破坏性地修改您要排序的列表:

In [177]: range(10)
Out[177]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [178]: range(10).sort()

In [179]:

也就是说,max找到列表中最大的元素,并且比你的方法更有效。

答案 5 :(得分:0)

在Python sort()中是一个就地操作。因此result.sort()会返回None,但会更改result进行排序。因此,为避免出现问题,请勿在致电result时覆盖sort()

答案 6 :(得分:0)

有没有理由不使用sorted功能? sort()仅在列表中定义,但sorted()适用于任何可迭代,并按您期望的方式运行。有关排序详情,请参阅this article

此外,因为在内部使用timsort,如果您需要对键1进行排序,然后对键2进行排序,则效率非常高。

答案 7 :(得分:0)

您不需要自定义功能来实现您想要实现的目标,首先需要了解您正在使用的方法!

在python中

sort()列表到位,即sort()的回复是None。列表本身是已修改,新列表已返回。

   
>>>results = ['list','of','items']
>>>results

['list','of','items']

>>>results.sort()
>>>type(results)

<type 'list'>

>>>results

['items','list','of']

>>>results = results.sort()
>>>results
>>>
>>>type(results)

<type 'NoneType'>

如您所见,当您尝试分配sort()时,您将不再拥有列表类型。