使用Python列表推导式类似于zip的用法

4

好的,所以我在使用多个“for”写Python列表推导式方面非常糟糕,但我想变得更好。我想确切地知道这行代码是否:

>>> [S[j]+str(i) for i in range(1,11) for j in range(3) for S in "ABCD"]

可以修改为返回类似于["A1","B1","C1","D1","A2","B2","C2","D2"...(等等)]的内容。
如果没有,是否有一个列表推导式可以返回相同的列表,即由"ABCD"和1到10的数字组合而成的字符串列表。
5个回答

7

你的循环过多了,根本不需要j

这样做就可以:

[S+str(i) for i in range(1,11) for S in "ABCD"]

1
您可以像这样使用 itertools.product
import itertools
print [item[1] + str(item[0]) for item in itertools.product(range(1, 11),"ABCD")]

输出

['A1', 'B1', 'C1', 'D1', 'A2', 'B2', 'C2', 'D2', 'A3', 'B3', 'C3', 'D3', 'A4',
 'B4', 'C4', 'D4', 'A5', 'B5', 'C5', 'D5', 'A6', 'B6', 'C6', 'D6', 'A7', 'B7',
 'C7', 'D7', 'A8', 'B8', 'C8', 'D8', 'A9', 'B9', 'C9', 'D9', 'A10', 'B10', 'C10',
 'D10']

1

我喜欢在列表推导式中看到多个for循环的方式就像嵌套循环。把下一个for循环视为嵌套在第一个循环中,这将使它变得更加容易。此外,补充一下Daniel的回答:

[S+str(i) for i in range(1,11)  for S in "ABCD"]

仅仅是:

new_loop=[]
for i in range (1,11):
    for S in "ABCD:
         new_loop.append(S+str(i))

1

每当您想将一个可迭代对象的所有元素与另一个可迭代对象的所有元素组合在一起时,请考虑使用itertools.product。它是两个集合(或列表)的笛卡尔积。

我找到了一个比现在提出的解决方案稍微更快的解决方案。比@daniel的解决方案快2倍以上(尽管他的解决方案看起来更优雅):

import itertools
[x + y for (x,y) in (itertools.product('ABCD', map(str,range(1,5))))]

这里的区别是我使用 map 将整数强制转换为字符串。将函数应用于向量通常比将其应用于单个项要快。

处理复杂的推导式时的一个普遍技巧:

当你有很多 for 循环和很多条件语句在推导式中时,将其拆分成几行,像这样:

[S[j]+str(i) for i in range(1,11)
             for j in range(3) 
             for S in "ABCD"]

在这种情况下,易读性的改变并不是很大,但是当你有大量条件语句和循环语句时,它会产生很大的差异。这就像嵌套for循环和if语句一样,但没有“:”和缩进。
看看使用常规for循环的代码:
ans = []
for i in range(1,11):
    for j in range(3): 
        for S in "ABCD": 
            ans.append(S[j] + str(i))

几乎相同的事情 :)

0
为什么不使用itertools.product?
>>> import itertools
>>> [ i[0] + str(i[1]) for i in itertools.product('ABCD', range(1,5))]
 ['A1', 'A2', 'A3', 'A4', 'B1', 'B2', 'B3', 'B4', 'C1', 'C2', 'C3', 'C4', 'D1', 'D2', 'D3', 'D4']

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