在python中展平列表

时间:2013-12-08 15:01:04

标签: python list

我见过很多关于如何在Python中展平列表的帖子。但我无法理解这是如何运作的:reduce(lambda x,y:x+y,*myList)

有人可以解释一下,这是如何运作的:

>>> myList = [[[1,2,3],[4,5],[6,7,8,9]]]
>>> reduce(lambda x,y:x+y,*myList)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

链接已发布:

How to print list of list into one single list in python without using any for or while loop?

Flattening a shallow list in Python

Flatten (an irregular) list of lists

如果有人认为这与其他帖子重复,我会在理解其工作后将其删除。

感谢。

4 个答案:

答案 0 :(得分:4)

reduce用简单的英语做的是,它需要两件事:

  1. 一个函数f
    1. 接受2个参数
    2. 返回使用这两个值计算的值
  2. 可迭代iter(例如liststr
  3. reduce计算f(iter[0],iter[1])(迭代的前两项)的结果,并跟踪刚刚计算出的这个值(称之为temp)。 reduce然后计算f(temp,iter[2]),现在跟踪这个新值。此过程一直持续到iter中的每个项目都已传递到f,并返回计算出的最终值。

    使用**myList传递给reduce函数是因为它需要迭代并将其转换为多个参数。这两行做同样的事情:

    myFunc(10,12)
    myFunc(*[10,12])
    

    对于myList,您使用的list只包含一个list。因此,将*置于前面会将myList替换为myList[0]

    关于兼容性,请注意reduce函数在Python 2中完全正常,但在Python 3中你必须这样做:

    import functools
    functools.reduce(some_iterable)
    

答案 1 :(得分:3)

相当于:

def my_reduce(func, seq, default=None):
    it = iter(seq)
    # assign either the first item from the iterable to x or the default value
    # passed to my_reduce 
    x = next(it) if default is None else default
    #For each item in iterable, update x by appying the function on x and y
    for y in it:
        x  = func(x, y)
    return x
... 
>>> my_reduce(lambda a, b: a+b, *myList, default=[])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> my_reduce(lambda a, b: a+b, *myList)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> from operator import add
>>> my_reduce(add, *myList)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> my_reduce(lambda a, b: a+b, ['a', 'b', 'c', 'd'])
'abcd'

reduce的文档字符串有一个非常好的解释:

reduce(...)
    reduce(function, sequence[, initial]) -> value

    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.

答案 2 :(得分:2)

首先,这是非常糟糕的方法。你知道吗。

reduce(f, [a, b, c, d])运行

f(f(f(f(a, b), c), d)

由于flambda x,y:x+y,因此相当于

((a + b) + c) + d

对于列表,a + b是列表的串联,因此这将连接每个列表。

这很慢,因为每一步都必须从头开始制作一个新列表。

答案 3 :(得分:1)

首先,我不知道为什么它被包裹在一个数组中,然后是splatted(*)。这将以相同的方式工作:

>>> myList = [[1,2,3],[4,5],[6,7,8,9]]
>>> reduce(lambda x,y:x+y,myList)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

说明:reduce采用一个带有两个参数的方法 - 累加器和元素。它使用每个元素调用方法,然后将累加器设置为lambda的结果。因此,您基本上将所有内部列表连接在一起。

以下是逐步说明:

  1. 累加器初始化为myList[0] [1,2,3]
  2. 使用[1,2,3][4,5]调用lambda,返回[1,2,3,4,5],分配给累加器
  3. 使用[1,2,3,4,5][6,7,8,9]调用lambda,返回[1,2,3,4,5,6,7,8,9]
  4. 不再剩余元素,因此reduce会返回