如何在 Python 中对元组列表列表进行平面映射? [复制]

Posted

技术标签:

【中文标题】如何在 Python 中对元组列表列表进行平面映射? [复制]【英文标题】:How to flatmap list of lists of lists of tuples in Python? [duplicate] 【发布时间】:2015-11-16 07:47:29 【问题描述】:

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

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? - 没有帮助

【问题讨论】:

您尝试过的其他代码是什么,有什么问题? 我没有收到错误,但它无法展平我的列表,因为所有示例都是针对列表列表的,例如 [[1,3,4],[4,3],[3 ]] 这不是我的情况 您应该在问题中发布您尝试过的内容。 【参考方案1】:

Python 具有展平一个嵌套级别的功能。它的名字很不幸itertools.chain.from_iterable()。如果你应用它 3 次,它会变平三个级别:

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

【讨论】:

我理解这一点,因为我对编程并不陌生,只对 python :) 但是如果它会更深呢?有没有更好的方法呢?对任何深度都有效 @maxpovver:这取决于你想要什么。如果你只是扁平化任意迭代,你也会扁平化你的元组。如果这是您想要的,您可以编写一个展平所有列表的递归函数。您还可以编写一个通用函数,将您想要展平的级别数作为参数。你可以做所有这些,但你没有要求它。 :) 如果我做对了,您的代码将无济于事:[ [ [[1,2,3], [1,2,3] ], [ [1,2,3] , [1,2,3, [1, 2, 3] ] ]. @maxpovver:不,它没有,因为这不是你想要的。 试过你的代码,它会丢失商品订单【参考方案2】:

试试这个:

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

这个答案类似于:https://***.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), ...]

【讨论】:

【参考方案3】:

如果您使用的是 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 模块已被弃用。

【讨论】:

以上是关于如何在 Python 中对元组列表列表进行平面映射? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何根据某些文本标准对元组列表进行分组/存储?

如何对元组列表进行分组?

如何按两个元素对元组列表进行排序?

如何根据另一个列表对元组列表进行排序

如何根据另一个列表中元组元素的顺序对元组列表进行排序?

python 数组和列表的区别