【问题标题】:Iterative string construction in Python while avoiding for loop [duplicate]Python 中的迭代字符串构造,同时避免 for 循环 [重复]
【发布时间】:2023-02-06 23:50:48
【问题描述】:

我想使用三个大写字母的所有组合创建一组身份,同时避免 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。作为结果,所有三个字母总是相同的。我可以微调这种方法以便一次迭代一个字母,还是我需要使用一种完全不同的方法?

【问题讨论】:

  • 你说你想简化你的代码,但你的代码已经真的很简单。也许是最简单的。为什么您认为避免循环会使它变得更简单?
  • @KellyBundy 谢谢!然而,我确实确信使用 for 循环是执行此操作的计算效率最低的方法,并且我确信我可以使用 map 函数或其他运行速度更快的方式来执行此操作。事实证明,即使使用 itertools 模块,我也无法在任何情况下避免循环。

标签: python iterator string-concatenation


【解决方案1】:

“我可以微调这种方法以便一次迭代一个字母,还是我需要使用一种完全不同的方法?” 是的……这将是 3 个独立的循环。使用map、循环或理解都没关系,在这种情况下它是语法糖,在这种情况下你必须经历所有的可能性,恕我直言,没有捷径。

您可以使用例如来自 itertoolsproduct 使其更具可读性:

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}')

【讨论】:

  • product,不是permutations
  • permutations 不会生成具有重复字符的字符串,如 AAA
  • 你是对的,product
【解决方案2】:

你只是在重新实现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 生成的三重奏构建字符串的偏好。

【讨论】:

    【解决方案3】:

    你基本上是这样做的:

    >>> [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'
    

    一次生成一个。

    (从 cmets,你也可以做这个生成器:

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

    这很酷...)

    【讨论】:

    • 又一个迭代器:starmap("ID_{}{}{}".format, product(ascii_uppercase, repeat=3))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2013-03-23
    • 2013-01-05
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多