Python中的迭代字符串构造同时避免for循环[duplicate]

dfuffjeb  于 2023-02-07  发布在  Python
关注(0)|答案(3)|浏览(112)
    • 此问题在此处已有答案**:

Avoiding nested for loops(3个答案)
9小时前关门了。
我想创建一个使用三个大写字母的所有组合的恒等式集,同时避免for循环以节省计算时间。我想拥有从ID_AAAID_ZZZ的恒等式。
我可以使用for循环来实现这一点:

> from string import ascii_uppercase 
> IDs = [] 
>  for id_first_letter in ascii_uppercase:   
>    for id_second_letter in ascii_uppercase:
>      for id_third_letter in ascii_uppercase:
>        IDs.append('ID_' + id_first_letter + id_second_letter + id_third_letter)

当然,我想简化这里的代码,我试过使用map函数,但我能想到的最好的是:

> from string import ascii_uppercase
> IDs = list(map(lambda x,y,z: 'ID_' + x + y + z,ascii_uppercase,ascii_uppercase,ascii_uppercase))

这是在所有字母之间同时迭代,所以我只能得到ID_AAAID_BBB,...,ID_ZZZ。所有三个字母总是相同的结果。我可以微调这种方法,以便一次迭代一个字母,还是需要使用完全不同的方法?

sr4lhrrt

sr4lhrrt1#

您只是重新实现了itertools.product

from itertools import product
from string import ascii_uppercase 

IDs = [''.join(["ID_", *t]) for t in product(ascii_uppercase, repeat=3)]

IDs = [f'ID_{x}{y}{z}' for x, y, z in product(ascii_uppercase, repeat=3)]

这取决于您对从product产生的三重奏构造字符串的偏好。

mlmc2os5

mlmc2os52#

“我可以微调这种方法,以便每次迭代一个字母,还是我需要使用一种完全不同的方法?”是的...这将是3个独立的循环。无论你使用map,循环或解析,在这种情况下,它是语法糖,你必须通过在这种情况下的所有可能性,没有捷径imho.
您可以使用例如itertools中的product来使其更具可读性:

from itertools import product
from string import ascii_uppercase 
IDs= []
for a,b,c in product(ascii_uppercase, repeat=3):
    IDs.append(f'ID_{a}{b}{c}')
ecfsfe2w

ecfsfe2w3#

您实际上是在这样做:

>>> [f'ID_{x}{y}{z}' for x in ascii_uppercase for y in ascii_uppercase for z in ascii_uppercase]
['ID_AAA', 'ID_AAB', 'ID_AAC', ... 'ID_ZZX', 'ID_ZZY', 'ID_ZZZ']

它也被称为Cartesian Product
你也可以直接使用itertools中的product:

>>> from itertools import product
>>> [f'ID_{x}{y}{z}' for x,y,z in product(ascii_uppercase, repeat=3)]
['ID_AAA', 'ID_AAB', 'ID_AAC', ... 'ID_ZZX', 'ID_ZZY', 'ID_ZZZ']

不要忘记,重构代码是“更好的”,这样在不必要的情况下就不会生成整个列表。
您可以执行以下操作:

>>> ids_gen=(f'ID_{x}{y}{z}' for x in ascii_uppercase for y in ascii_uppercase for z in ascii_uppercase)
>>> next(ids_gen)
'ID_AAA' # and so on until exhausted...

或者这个:

>>> ids_gen=(f'ID_{x}{y}{z}' for x,y,z in product(ascii_uppercase, repeat=3))
>>> next(ids_gen)
'ID_AAA'

一次产生一个。
(From注解,你也可以做这个生成器:

from itertools import product, starmap
ids_gen=starmap("ID_{}{}{}".format, product(ascii_uppercase, repeat=3))

这很酷...)

相关问题