在Python中将列表展平

15

我有一个像这样的列表:

[[(video1,4)], [(video2,5),(video3,8)], [(video1,5)], [(video5, 7), (video6,9)]...]

这个列表中的每个项目可能包含单个数据对或元组,我想将此列表更改为

[(video1,4),(video2,5),(video3,8),(video1,5),(video5,7),(video6,9)...]

那么就这样做:

for item in list:
    reqs = reqs + item[1]
    b.append(item[0])
c = set(b)

我不知道如何更改列表结构,或者基于原始列表进行相同的计算。


在示例列表中,您需要 ... 吗?如果没有它,它也可以是一个可行的示例。 - jamylak
1
你实际上最终想要达到什么目标?是一组“videoX”变量和你列出的其他数字之和的集合c吗? - Shep
@jamylak 不,这意味着还有很多类似的数据,我不想列出它们所有。 - manxing
@Shep 是的,这个列表包含了很多数据,不仅仅是我在这里列出的那些,但基本上这就是我想做的。 - manxing
1
这个回答解决了你的问题吗?如何将一个列表中的多个子列表展开成一个平面列表? - questionto42
7个回答

15

使用列表推导式可以非常简单地完成这个任务。这个例子已经在Python文档这里中进行了说明。

>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

以下是您要实现的解决方案。根据您的示例,这是最简单的解决方案。

In [59]: your_list = [[('video1',4)], [('video2',5),('video3',8)], [('video1',5)], [('video5', 7), ('video6',9)]]

In [60]: improved_list = [num for elem in your_list for num in elem]

In [61]: improved_list
Out[61]: 
[('video1', 4),
 ('video2', 5),
 ('video3', 8),
 ('video1', 5),
 ('video5', 7),
 ('video6', 9)]

有趣,但很难凭记忆做到完美。 - Wolf

14
如果这个列表是单层嵌套的(列表中还包含列表),你可以使用我经常使用的方法:
flat_list = sum(list_of_lists, [])

之所以这个方法可行,是因为sum()函数简单地将列表中的元素相加,而在Python中进行列表元素的加和操作跟预期一样 :)

注意:这种方法效率较低,有些人认为不易读。


不符合Python风格。点赞只是为了这个想法。 - questionto42

11

要将一个级别压平,您可以使用itertools.chain.from_iterable()

flattened_list = itertools.chain.from_iterable(my_list)

@Marcin:你是对的,这就是 NumPy 中它的称呼。 :) - Sven Marnach
1
证明数字对你有害,好像需要证明一样 ;) - Marcin

10

2
这里有另一个(没有使用库)的例子:
def plus(a,b): return a + b
reduce(plus, your_list)

1
你为什么要创建一个命名函数而不是一个lambda函数? - Marcin
1
只是为了清晰,没有特别原因。 - rodion
这是(Python 3 中的 functools reduce)最慢的解决方案。 - misantroop

1

试一试:

from itertools import chain 

c = set()
reqs = 0
for vid, number in chain(*your_list): 
    c.add(vid)
    reqs += number 

同时请参阅相关帖子 Python中扁平化浅层列表

使用chain.from_iterable(list)而不是chain(*list)应该没有显著的性能提升,但前者确实看起来更简洁。


-1

从数据结构中提取所有元组...

def get_tups(y):
    z = []
    if y:
        for x in y:
            if isinstance(x, tuple):
                z.append(x)
            else:
                z.extend(get_tups(x))
    return z

或许...


如果我调用 get_tups([('foo',)]) 会发生什么? - Marcin
由于输入包含1个元组,因此您将获得一个包含1个元组的列表。换句话说,输出将与输入相同 ;) - Gwyn Howell
如果我第二次调用它会发生什么?这里有一个提示:http://ideone.com/zgMzq - Marcin
我已经解释了为什么会发生这种情况:z=[] 作为 def 语句的一部分被评估。顺便说一下,你的函数也无法处理循环输入:http://ideone.com/YOaPS - Marcin
太棒了。你可以编辑你的答案 - 这绝对是鼓励的。 - Marcin
显示剩余6条评论

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