【问题标题】:Variable number of predictable for loops in PythonPython中可变数量的可预测for循环
【发布时间】:2015-08-17 21:17:07
【问题描述】:

我试图想出一种方法来从 20 个字符的字母表中生成所有可能的唯一字符串,其中字符串中的顺序无关紧要,并且字符串的长度可以变化。因此,例如,对于长度为 3 的字符串,可能的字符串为 AAA、AAB、AAC 等,但不包括 BAA 或 CAA。我想出了一种使用itertools.product() 的方法,但它的计算成本非常高。最简单的方法是简单地使用嵌套的 for 循环。例如,要生成所有长度为 4 的字符串:

alphabet = ["A","C","D","E","F","G","H","I","K","L",
            "M","N","P","Q","R","S","T","V","W","Y"]
combos = []
for a in range(len(alphabet)):
    for b in range(a,len(alphabet)):
        for c in range(b,len(alphabet)):
            for d in range(c,len(alphabet)):
                combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d])

现在,通过更改 for 循环的数量,可以轻松地为任何长度的字符串完成此操作。鉴于 for 循环序列本身是相当可预测的,有没有办法简化此代码,而不是让 if length == 3 运行三个 for 循环和 if length == 4 运行四个循环?我现在能想到的唯一方法是一堆if-elif 声明:

if length == 3:
    for a in range(len(alphabet)):
        for b in range(a,len(alphabet)):
            for c in range(b,len(alphabet)):
                combos.append(alphabet[a] + alphabet[b] + alphabet[c])
elif length == 4:
    for a in range(len(alphabet)):
        for b in range(a,len(alphabet)):
            for c in range(b,len(alphabet)):
                for d in range(c,len(alphabet)):
                    combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d])

除了覆盖一堆可能的长度值之外,还有什么更简单的方法吗?

【问题讨论】:

  • 您能否详细说明您使用itertools.product 尝试/失败的解决方案?你的方式应该在计算上更加昂贵。
  • @Two-BitAlchemist:不,OP 的代码更好,因为它只生成他需要的代码。使用产品,在 4 个字母的情况下,您将丢弃 151145/160000 个结果。

标签: python python-3.x nested-loops


【解决方案1】:

IIUC,你可以直接使用itertools.combinations_with_replacement。

>>> list(map(''.join, combinations_with_replacement(["a","b","c"],2)))
['aa', 'ab', 'ac', 'bb', 'bc', 'cc']
>>> list(map(''.join, combinations_with_replacement(["a","b","c"],3)))
['aaa', 'aab', 'aac', 'abb', 'abc', 'acc', 'bbb', 'bbc', 'bcc', 'ccc']
>>> list(map(''.join, combinations_with_replacement(alphabet,4))) == orig(alphabet)
True

(其中orig 只是您将原始代码包装到一个函数中)。

【讨论】:

  • 只是想回答同样的问题,产品会给出完全不同的输出
  • @PadraicCunningham:那么我不确定我是否理解您对 OP 的评论问题 - OP 的代码比产品更有效,因为他只生成他需要的代码,而不是查看所有并过滤掉他不想要的。
  • 我最初没有看 OP 的代码,我认为他们想要产品,因为他们正在使用产品
  • 恐怕我也做了同样的事情。我根据问题文本而不是代码做出假设。
  • 这正是我想要的,谢谢。我对不同的实现进行了计时,以查看它们与长度为 6 的字符串的比较:itertools.product(): 72.5235 s, manual nest: 0.1549 s, itertools.combinations_with_replacement(): 0.1536 s
【解决方案2】:
  1. code for itertools.product 完全符合您的要求,并且比嵌套循环更高效

  2. 我怀疑你真正想要的是itertools.combinations_with_replacement

【讨论】:

    猜你喜欢
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2019-02-02
    相关资源
    最近更新 更多