如何在python中提取单行解析中的子列表项?

时间:2013-07-08 10:53:01

标签: python python-3.x list-comprehension

我目前正在学习python中列表推导的概念。但是,当我迭代的列表包含相同或不同长度的子列表时,我遇到了很大的问题。例如,我想将union_set()的代码转换为单行理解:

def union_set(L):
    S_union = set()

    for i in range(len(L)):
        S_union.update(set(L[i]))

    return S_union


L1 = [1, 2, 3]
L2 = [4, 5, 6]
L3 = [7, 8, 9]

L = [L1, L2, L3]
print(L)

print(union_set(L))

我很确定这应该是可能的(可能通过'某种方式'解包子列表的内容(?)),但我很害怕我在这里遗漏了一些东西。有人可以帮忙吗?

4 个答案:

答案 0 :(得分:4)

使用list-comprehension,您可以执行以下操作:

>>> L1 = [1, 2, 3]
>>> L2 = [4, 5, 6]
>>> L3 = [7, 8, 9]
>>> L = [L1, L2, L3]
>>> s=set([x for y in L for x in y])
>>> s
set([1, 2, 3, 4, 5, 6, 7, 8, 9])

y迭代子列表,而x迭代y中的项目。

答案 1 :(得分:3)

使用空的set.union

L1 = [1, 2, 3]
L2 = [4, 5, 6]
L3 = [7, 8, 9]

print set().union(L1, L2, L3)

在您的代码中使用:

L = [L1, L2, L3]

def union_set(L):
    return set().union(*L)

答案 2 :(得分:2)

使用*进行解包并将解压缩的项目传递给set.union

>>> L = [L1, L2, L3]
>>> set.union(*(set(x) for x in L))
set([1, 2, 3, 4, 5, 6, 7, 8, 9])

使用itertools的高效版本:

>>> from itertools import islice
>>> set.union(set(L[0]),*islice(L,1,None))
set([1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> from itertools import chain
>>> set(chain.from_iterable(L))
set([1, 2, 3, 4, 5, 6, 7, 8, 9])

时间比较:

>>> L = [L1, L2, L3]*10**5

>>> %timeit set.union(*(set(x) for x in L))
1 loops, best of 3: 416 ms per loop

>>> %timeit set(chain.from_iterable(L))               # winner
1 loops, best of 3: 69.4 ms per loop

>>> %timeit set.union(set(L[0]),*islice(L,1,None))
1 loops, best of 3: 78.6 ms per loop

>>> %timeit set().union(*L)
1 loops, best of 3: 105 ms per loop

>>> %timeit set(chain(*L))
1 loops, best of 3: 79.2 ms per loop

>>> %timeit s=set([x for y in L for x in y])
1 loops, best of 3: 151 ms per loop

答案 3 :(得分:1)

您可以像这样使用itertools.chain

>>> L1 = [1, 2, 3]
>>> L2 = [4, 5, 6]
>>> L3 = [7, 8, 9]
>>> L = [L1,L2,L3]

>>> set(itertools.chain(*L))
set([1, 2, 3, 4, 5, 6, 7, 8, 9])

*解压缩列表,chain从子列表中创建一个列表。