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"...(etc.)]

如果没有,如果有一个列表推导可以返回相同的列表,即“ABCD”和从1到10的数字的所有组合的字符串列表。

4

5 回答 5

7

你那里有太多的循环。你根本不需要j

这可以解决问题:

[S+str(i) for i in range(1,11) for S in "ABCD"]
于 2013-11-08T13:22:57.830 回答
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']
于 2013-11-08T13:25:18.460 回答
1

我喜欢在列表理解中看到多个 for 循环的方式就像嵌套循环。将下一个 for 循环视为嵌套在第一个循环中的循环,这将使其变得更加容易。添加到丹尼尔的答案:

[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))
于 2013-11-08T13:26:50.280 回答
1

每次您考虑将所有元素(如果一个可迭代对象)与另一个可迭代对象的所有元素相结合时,请考虑一下 itertools.product。它是两个集合(或列表)的笛卡尔积。

我找到了一个比这里介绍的解决方案稍微快一点的解决方案。并且比@daniel 解决方案快 2 倍以上(尽管他的解决方案看起来更加优雅):

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

这里的区别是我使用 map 将 int 转换为字符串。在向量上应用函数通常比在单个项目上应用它们更快。

处理复杂理解时的一般提示:

当你的理解中有很多 for 和很多条件时,把它分成几行,像这样:

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

在这种情况下,易读性的变化并没有那么大,但是当你有很多条件句和很多 fors 时,它就会产生很大的不同。这就像编写 for 循环和嵌套的 if 语句,但没有“:”和标识。

查看使用常规 fors 的代码:

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

几乎一样的东西:)

于 2013-11-08T14:18:04.303 回答
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']
于 2013-11-08T13:25:58.987 回答