我目前正在学习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))
我很确定这应该是可能的(可能通过'某种方式'解包子列表的内容(?)),但我很害怕我在这里遗漏了一些东西。有人可以帮忙吗?
答案 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
从子列表中创建一个列表。