我最近遇到了这种符号
a = [1,2,3,4]
b = [2,4,6]
c = [(x,y,z) for x in a for y in b for z in a]
首先,我不知道如何在创建c
时搜索符号,这种类型的结构是否有名称?
此外,我确信c
可以更新为不允许x
等于z
。请你能帮帮我吗?
我尝试了各种各样的事情
c = [(x,y,z) for x in a for y in b for z in a for x != z]
但到目前为止,我无法找到有效的内容,甚至是有效的语法。
我想要完成的是找到(a,b,a)
的每个组合,其中a
只能在每一行中使用一次,因此结果将是
[(1, 2, 2),
(1, 2, 3),
(1, 2, 4),
(1, 4, 2),
(1, 4, 3),
(1, 4, 4),
(1, 6, 2),
(1, 6, 3),
(1, 6, 4),
(2, 2, 1),
(2, 2, 3),
(2, 2, 4),
(2, 4, 1),
(2, 4, 3),
(2, 4, 4),
(2, 6, 1),
(2, 6, 3),
(2, 6, 4),
(3, 2, 1),
(3, 2, 2),
(3, 2, 4),
(3, 4, 1),
(3, 4, 2),
(3, 4, 4),
(3, 6, 1),
(3, 6, 2),
(3, 6, 4),
(4, 2, 1),
(4, 2, 2),
(4, 2, 3),
(4, 4, 1),
(4, 4, 2),
(4, 4, 3),
(4, 6, 1),
(4, 6, 2),
(4, 6, 3)]
由于
答案 0 :(得分:3)
它被称为 list comprehension ,您可以在其中使用逻辑if
来过滤返回列表中的结果:
>>> a = [1,2,3,4]
>>> b = [2,4,6]
# if condition to skip results where `x` equals `z` v
>>> c = [(x,y,z) for x in a for y in b for z in a if x != z]
>>> c
[(1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 4, 2), (1, 4, 3), (1, 4, 4), (1, 6, 2), (1, 6, 3), (1, 6, 4), (2, 2, 1), (2, 2, 3), (2, 2, 4), (2, 4, 1), (2, 4, 3), (2, 4, 4), (2, 6, 1), (2, 6, 3), (2, 6, 4), (3, 2, 1), (3, 2, 2), (3, 2, 4), (3, 4, 1), (3, 4, 2), (3, 4, 4), (3, 6, 1), (3, 6, 2), (3, 6, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 6, 1), (4, 6, 2), (4, 6, 3)]
您可以使用itertools.product
获得相同的行为,而不是使用嵌套列表理解:
>>> from itertools import product
>>> [(x,y,z) for x, y, z in product(a, b, a) if x !=z]
[(1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 4, 2), (1, 4, 3), (1, 4, 4), (1, 6, 2), (1, 6, 3), (1, 6, 4), (2, 2, 1), (2, 2, 3), (2, 2, 4), (2, 4, 1), (2, 4, 3), (2, 4, 4), (2, 6, 1), (2, 6, 3), (2, 6, 4), (3, 2, 1), (3, 2, 2), (3, 2, 4), (3, 4, 1), (3, 4, 2), (3, 4, 4), (3, 6, 1), (3, 6, 2), (3, 6, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 6, 1), (4, 6, 2), (4, 6, 3)]
答案 1 :(得分:1)
这是list comprehension
,过滤条件的正确语法是:
c = [(x,y,z) for x in a for y in b for z in a if x != z]
答案 2 :(得分:1)
用于创建c
的语法称为list comprehension。几乎你的确切情况是这些文档中的第四个代码示例:
列表推导由括号组成,括号中包含一个表达式,后跟一个for子句,然后是零个或多个for或if子句。结果将是一个新列表,该列表是通过在其后面的for和if子句的上下文中计算表达式得到的。例如,如果列表不相等,则此listcomp将两个列表的元素组合在一起:
>>> [(x,y)对于[1,2,3]中的x,对于[3,1,4]中的y,如果x!= y]
[(1,3),(1,4),(2,3),(2,1),(2,4),(3,1),(3,4)]
您需要做的就是将上次for
更改为if
:
c = [(x,y,z) for x in a for y in b for z in a if x != z]
答案 3 :(得分:0)
为了多样化,我想添加以下基于itertools.product
和规避 if
检查的解决方案。
from itertools import product
a = [1,2,3,4]
b = [2,4,6]
c = []
for i, item in enumerate(a):
c.extend((item, x, y) for x, y in product(b, a[:i] + a[i+1:]))
print(c)
制造
[(1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 4, 2), (1, 4, 3), (1, 4, 4), (1, 6, 2), (1, 6, 3), (1, 6, 4), (2, 2, 1), (2, 2, 3), (2, 2, 4), (2, 4, 1), (2, 4, 3), (2, 4, 4), (2, 6, 1), (2, 6, 3), (2, 6, 4), (3, 2, 1), (3, 2, 2), (3, 2, 4), (3, 4, 1), (3, 4, 2), (3, 4, 4), (3, 6, 1), (3, 6, 2), (3, 6, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 6, 1), (4, 6, 2), (4, 6, 3)]
我也做了一些时间来比较使用的不同方法:
from timeit import timeit
setup = '''
from itertools import product
def list_comp(a, b):
return [(x,y,z) for x in a for y in b for z in a if x != z]
def itertools_listComp(a, b):
return [(x,y,z) for x, y, z in product(a, b, a) if x !=z]
def itertools_forLoop(a, b):
c = []
for i, item in enumerate(a):
c.extend((item, x, y) for x, y in product(b, a[:i] + a[i + 1:]))
return c
a = [1, 2, 3, 4]
b = [2, 4, 6]
'''
print('list_comp:', timeit(stmt="list_comp(a, b)", setup=setup, number=1000))
print('itertools_forLoop:', timeit(stmt="itertools_forLoop(a, b)", setup=setup, number=1000))
print('itertools_listComp:', timeit(stmt="itertools_listComp(a, b)", setup=setup, number=1000))
结果是:
list_comp: 0.0050
itertools_listComp: 0.0056
itertools_forLoop: 0.0086
所以似乎普通列表理解是最快的。此行为也会因较大的a
列表而持续存在。