将Python列表元素映射到多个元素,避免嵌套列表

时间:2016-05-27 17:11:41

标签: python list

这样我可以通过映射另一个列表中的每个元素来构建一个新列表:

# turn [0,5,10,15] into [1,6,11,16]
[ x+1 for x in range(0,20,5) ]

但我希望每个元素在我的新列表中产生两个元素。我怎样才能做到这一点?以下是我的尝试:

# turn [0,5,10,16] into [0,1,-5,6,-10,11,-15,16]
# does not work! gives [[0,1],[-5,6],[-10,11],[-15,16]]
[ [-x,x+1] for x in range(0,20,5) ]

# turn [0,5,10,16] into [0,1,-5,6,-10,11,-15,16]
# does not work! gives [(0,1),(-5,6),(-10,11),(-15,16)]
[ (-x,x+1) for x in range(0,20,5) ]

当然,我可以创建列表列表,然后以某种方式展平它,但是有更简洁的方法吗?

4 个答案:

答案 0 :(得分:4)

您需要使用两个循环:

>>> [t for x in range(0,20,5) for t in [-x,x+1] ]
[0, 1, -5, 6, -10, 11, -15, 16]

或者,如果您要处理更大的数据集,可以使用itertools.chain()

>>> from itertools import chain
>>> 
>>> list(chain.from_iterable([-x,x+1] for x in range(0,20,5)))
[0, 1, -5, 6, -10, 11, -15, 16]
>>> 

请注意,如果您只想迭代结果,则不必将结果转换为list,因为chain.from_iterable返回迭代器并且在内存使用方面进行了更优化。

答案 1 :(得分:2)

据我所知,列表理解(一个for)一次不能超过一个元素。你可以:

  • 展平它(from itertools import chain
  • 使用如下所示的函数并将其用作生成器:

    def myFunc(elements):
        for elem in elements:
            yield -elem
            yield elem + 1
    

答案 2 :(得分:0)

您可以使用functools.reduce(如果您使用的是Python 2.x,则无需导入):

from functools import reduce

flat_list = reduce(lambda x, y: x + y, [[-x, x+1] for x in range(0, 20, 5)], [])

或者,甚至更好,正如@Thrustmaster所指出的那样:

flat_list = sum(([-x, x+1] for x in range(0, 20, 5)), [])

答案 3 :(得分:0)

请注意您希望was proposed but rejected添加到python的确切符号:

  

此PEP的早期迭代允许将列表,集合和字典理解中的运算符解压缩为容器的可迭代运算符:

>>> ranges = [range(i) for i in range(5)]
>>> [*item for item in ranges]
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]

使用此被拒绝的语法,您的案例如下:

[ *(-x,x+1) for x in range(0,20,5) ]

但是,由于列表理解目前一次只支持一个元素,你也可以简单地遍历其他元素:

[ item for x in range(0,20,5)
         for item in (-x,x+1) ]