【问题标题】:Sorting A List Comprehension In One Statement在一个语句中对列表理解进行排序
【发布时间】:2012-07-11 13:36:50
【问题描述】:

今天早上在编写脚本时,我注意到了一些我没有预料到的事情。我尝试使用列表推导并将其全部排序在一个语句中,并得到了令人惊讶的结果。以下代码总结了我的一般用例,但针对这个问题进行了简化:

Transaction = namedtuple('Transaction', ['code', 'type'])

my_list = [Transaction('code1', 'AAAAA'), Transaction('code2', 'BBBBB'), Transaction('code3', 'AAAAA')]

types = ['AAAAA', 'CCCCC']

result = [trans for trans in my_list if trans.type in types].sort(key = lambda x: x.code)

print result

输出:

None

如果我使用推导式创建列表,然后在事后对其进行排序,一切都很好。我很好奇为什么会这样?

【问题讨论】:

  • sort 方法就地对列表进行排序,然后返回None

标签: python list-comprehension


【解决方案1】:

方法list.sort() 正在对列表进行适当的排序,并且作为所有变异方法,它返回None。使用内置函数sorted() 返回一个新的排序列表。

result = sorted((trans for trans in my_list if trans.type in types),
                key=lambda x: x.code)

您也可以使用速度稍快的operator.attrgetter("code"),而不是lambda x: x.code

【讨论】:

    【解决方案2】:

    在列表上调用.sort 会返回None。然后将此结果分配给result,这是完全合理的。

    换句话说,您使用列表解析匿名创建一个列表,然后调用.sort,然后列表丢失,而.sort 调用的结果存储在result 变量中。

    正如其他人所说,您应该使用sorted() 内置函数来返回一个列表。 (sorted() 返回列表的排序副本。)

    【讨论】:

      【解决方案3】:

      你想要sorted 内置函数。 sort 方法对列表进行就地排序并返回None

      result = sorted([trans for trans in my_list if trans.type in types],key = lambda x: x.code)
      

      这可以通过以下方式做得更好:

      import operator
      result = sorted( (trans for trans in my_list if trans.type in types ), key=operator.attrgetter("code"))
      

      【讨论】:

      • 请注意,将列表解析传递给sorted() 会导致生成列表的副本。这不一定会变慢,但可能会导致更高的内存消耗。
      • 您需要将生成器表达式括在括号中。
      • @SvenMarnach -- 你不需要括号吧? sorted( x for x in xrange(10) ) 对我来说很好用
      • 如果有第二个参数,你确实需要它们。如果生成器表达式是唯一的参数,您可以将它们作为特殊例外排除在外。
      • @SvenMarnach 你的括号是对的——我想这是一种特殊情况,足以打破规则......谢谢(每天学习新东西:)。另外,list comp 真的占用那么多内存吗?列表中的所有对象都已经存在——在我看来,您实际上只是在创建列表 + len(lst)*sizeof(pointer) 的开销,但我不知道这是如何实现的细节东西确实有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      相关资源
      最近更新 更多