【问题标题】:How can I use a list comprehension to extend a list in python? [duplicate]如何使用列表推导来扩展 python 中的列表? [复制]
【发布时间】:2011-08-22 06:33:27
【问题描述】:

我没有使用 Python 的经验,我经常编写(简化的)如下代码:

accumulationList = []
for x in originalList:
    y = doSomething(x)
    accumulationList.append(y)
return accumulationList

然后在我的测试通过后,我重构为

return [doSomething(x) for x in originalList]

但假设结果有点不同,我的循环看起来像这样:

accumulationList = []
for x in originalList:
    y = doSomething(x)
    accumulationList.extend(y)
return accumulationList

doSomething 列表返回一个列表。完成此任务的最 Pythonic 方式是什么?显然,前面的列表推导会给出一个列表列表。

【问题讨论】:

  • @chris_rands -- 在提出问题 7.5 年后将问题标记为骗子似乎有点奇怪 -- 它并没有起到将 OP 引导到副本的目的,并且问题不够相似,合并是一种选择。 /耸肩

标签: python list for-loop nested list-comprehension


【解决方案1】:

你的意思是这样的吗?

accumulationList = []
for x in originalList:
    accumulationList.extend(doSomething(x))
return accumulationList

或更短的代码(但不是最佳的):

return sum((doSomething(x) for x in originalList), [])

或相同:

return sum(map(doSomething, originalList), [])

感谢@eyquem 的提示(如果使用 Python 2.x):

import itertools as it

return sum(it.imap(doSomething, originalList), [])

【讨论】:

  • return sum(map(doSomething, originalList)), []) 如果 Python 2 使用 imap 更好。如果使用 Python 3 则正确
【解决方案2】:

Python 的就地添加运算符(+=,在 operator 模块中以 iadd 的形式提供)等效于列表的 .extend。将其与reduce 配对以获得您想要的。

import operator

reduce(operator.iadd, (doSomething(x) for x in originalList)
, accumulation_list)

【讨论】:

    【解决方案3】:

    我认为这种情况没有特殊的语法。但是你可以缩短 for 循环:

    accumulationList += doSomething(x)
    

    如果你坚持,你可以使用函数式编程来扁平化列表:

    result = reduce(lambda a,b: a+b, [[i,i*2] for i in range(3)])
    

    但我不会称它为 pythonic,我认为它比 for 循环更难阅读。

    【讨论】:

      【解决方案4】:

      我认为涉及 add 或 iadd 的答案在二次时间内运行,这可能不好。我会尝试:

      from itertools import chain
      accumulation_list = list(chain.from_iterable(doSomething(x) for x in originalList))
      

      【讨论】:

        【解决方案5】:

        列表理解更简单、更简洁:

        [y for x in originalList for y in doSomething(x)]
        

        【讨论】:

        • 很大的改进!当我问这个问题时,我不必使用嵌套列表理解。
        【解决方案6】:

        Functionally,您可以将itertools.chainmap 一起使用。对于输入列表L

        res = list(chain.from_iterable(map(doSomething, L)))
        

        如果您需要迭代器,只需删除 list 调用即可。这是一个演示:

        def doSomething(value):
            return [value * i for i in range(1, 4)]
        
        def original(originalList):
            accumulationList = []
            for x in originalList:
                y = doSomething(x)
                accumulationList.extend(y)
            return accumulationList
        
        def new(L):
            return list(chain.from_iterable(map(doSomething, L)))
        
        x = [1, 2, 3]
        
        assert original(x) == new(x)
        
        print(new(x))
        
        [1, 2, 3, 2, 4, 6, 3, 6, 9]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-04
          • 2019-10-01
          • 1970-01-01
          • 2016-05-01
          相关资源
          最近更新 更多