如何在Python中平面映射元组列表列表?

时间:2015-08-22 12:16:15

标签: python list python-2.7

我正在使用日历并从中接收元组列表列表

calendar.Calendar.yeardays2calendar(calendar.Calendar(), year, 1))

输出是:

[[[[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6)], [(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6)], [(12, 0), (13, 1),...

我想将它平面映射到简单的元组列表,保存它们的顺序。在python 2.7中将任何深度的地图列表放到普通列表中的最佳方法是什么?

我想要的例子:

[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6),(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6), (12, 0), (13, 1)...

其他问题的试用代码 - 没有帮助。抱歉愚蠢的问题,我是python的新手

UPD我尝试了python list comprehensions; compressing a list of lists?的功能 - 没有帮助

3 个答案:

答案 0 :(得分:3)

Python有一个函数来展平一个嵌套级别。它以不幸的名字itertools.chain.from_iterable()为准。如果你应用它三次,它将展平三个级别:

import itertools
flatten1 = itertools.chain.from_iterable
flattened_data = flatten1(flatten1(flatten1(your_data)))
for a, b in flattened_data:
    # whatever

更一般地说,一个平展n级别的函数将是

def flatten_n(n, iterable):
    for x in reduce(apply, [itertools.chain.from_iterable] * n, iterable):
        yield x

递归展平所有列表的函数可能如下所示:

def flatten_lists(a):
    if isinstance(a, list):
        for b in a:
            for x in flatten_lists(b):
                yield x
    else:
        yield a

答案 1 :(得分:3)

试试这个:

def flatten(x):
    if isinstance(x, list):
        return [a for i in x for a in flatten(i)]
    else:
        return [x]

此答案与此类似:https://stackoverflow.com/a/2158522/1628832但检查特定的list类型而不是迭代。

为了优化,内存效率等,您也可以使用yield操作。

演示

>>> year = 2015
>>> x = calendar.Calendar.yeardays2calendar(calendar.Calendar(), year, 1)
>>> flatten(x)
[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6), (12, 0), (13, 1), (14, 2), (15, 3), (16, 4), (17, 5), (18, 6), (19, 0), (20, 1), (21, 2), (22, 3), (23, 4), (24, 5), (25, 6), ...]

答案 2 :(得分:0)

如果您使用的是Python 2,则以下一个班轮解决方案目前可以使用:

import compiler, itertools

lpairs = [[[[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6)], [(5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6)], [(12, 0), (13, 1)]]]]

print [(x,y) for x,y in itertools.izip(*[iter(compiler.ast.flatten(lpairs))]*2)]

给出:

[(0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5), (11, 6), (12, 0), (13, 1)]

请注意,Python compiler模块已被弃用。