Python遍历嵌套列表以按索引序列创建新列表

11

如何遍历一个列表的列表,例如:

[[1,2,3,4], [5,6], [7,8,9]]

通过获取每个列表的第一项、第二项等等,构建一个新列表,因此上面的内容变成了这样:

[1, 5, 7, 2, 6, 8, 3, 9, 4]
5个回答

12

你可以使用列表推导式与 itertools.izip_longest(或 Python 3 中的 zip_longest)一起使用。

from itertools import izip_longest
a = [[1,2,3,4], [5,6], [7,8,9]]
[i for sublist in izip_longest(*a) for i in sublist if i is not None]
# [1, 5, 7, 2, 6, 8, 3, 9, 4]

4
您将会失去任何0,您应该检查是否为None。 - Padraic Cunningham
5
在Python 3中,名称已更改为zip_longest - pp_
@9000 已更改。谢谢 :-) - Julien Spronck
@pp_ 谢谢,我已将其添加到答案中。 - Julien Spronck
2
如果你想要更加高端一些,这个等同于 list(filter(lambda x: x is not None, chain(*zip_longest(*a)))) - Paul
显示剩余3条评论

6
只要你知道None不会出现,你就可以利用map()在没有函数的情况下工作的方式:
outlist = [y for sub in map(None, *inlist) for y in sub if not y is None]

4
DRY: itertools有一个配方似乎非常适合这个任务:roundrobin
from itertools import cycle, islice

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    # Recipe credited to George Sakkis
    pending = len(iterables)
    nexts = cycle(iter(it).next for it in iterables)
    while pending:
        try:
            for next in nexts:
                yield next()
        except StopIteration:
            pending -= 1
            nexts = cycle(islice(nexts, pending))

l = [[1,2,3,4], [5,6], [7,8,9]]

print (list(roundrobin(*l)))
#[1, 5, 7, 2, 6, 8, 3, 9, 4]

这仅适用于Python 2,Python 3版本可以在此处找到:(https://docs.python.org/3/library/itertools.html)。 - pp_
你是对的,@pp_,Python 2使用属性next,而Python 3使用__next__ - chapelo
我认为 next(iter(it)) 对于两种情况都可以工作,对吗? - Paul
@Paul:是的,但在这段代码中,你需要使用functools.partial或lambda。 - Kevin

1
如果不想使用任何导入,您可以手动完成此操作。
保留N个不同的计数器,其中n是列表中子列表的数量,并在从该子列表添加新元素时逐个递增。 在添加它们时,您应控制相应集合的计数器必须是所有其他计数器中最小的,如果所有列表都有剩余元素。当您添加列表的最后一个元素时,您可以将其计数器增加到类似于9999的值,以保护我们的最小规则。
这将更难实现,我建议您不要以这种方式实现,但如果您不想导入任何内容或想为自己的级别提供编程挑战,这也是一种可能性。

0

如果过滤掉None,那么如果你想保留的子列表中有None值,这种解决方案就不起作用了。为了解决这个问题,你可以使用列表推导式来迭代最长子列表的索引,并且只有在索引范围内时才添加子列表项。

a = [[1,2,3,4],[5,6,None],[7,8,9]]
range_longest = range(max(map(len, a)))
[sublist[i] for i in range_longest for sublist in a if i < len(sublist)]
# [1, 5, 7, 2, 6, 8, 3, None, 9, 4]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接