【问题标题】:Python 2.7: iterate over all combinations of a string in one line of codePython 2.7:在一行代码中迭代字符串的所有组合
【发布时间】:2015-12-07 03:47:16
【问题描述】:

我正在尝试遍历长度为 1 到 8(含)之间的 string 的所有可能组合。 我的主要目标是让代码尽可能少。为此,我目前正在使用 Python 的 itertools 库:

import itertools, string
for i in xrange(1, 9):
    for x in itertools.imap(''.join, itertools.product(string.letters + string.digits + string.punctuation, repeat = i)):
        if x == some_string:
            # do something, like print x
            print x  
            break
    else:
        continue
    break

我希望能够在一行中进行迭代,所以我可以将break 一次性从内部和外部for 循环中取出,并且不需要else:continue、@ 987654328@ 等类似这样的东西:(使用嵌套的for 循环)

for x in (itertools.imap(''.join, itertools.product(string.letters + string.digits + string.punctuation, repeat = i)) for i in xrange(1, 9)):
    if x == some_string:
        print x
        break

但是,x 原来是<itertools.imap object>。所以我尝试迭代x,使用更多嵌套的for循环(因为如果我使用内部for循环,我将不得不再次break多次):

for y in (x for x in (itertools.imap(''.join, itertools.product(string.letters + string.digits + string.punctuation, repeat = i)) for i in xrange(1, 9))):
    if y == some_string:
        print y
        break

不幸的是,这仍然行不通; y 在某种程度上仍然是 <itertools.imap object>。我是一名自学的 Python 程序员,generatorsiterables 等有时让我感到困惑。有人可以帮我把迭代降到一行吗?非常感谢。

【问题讨论】:

  • 遍历所有这些组合是一种可怕的检查some_string是否是其中之一的方法。
  • 我同意;然而,这是我得到的任务。
  • 这样......你将拥有Memory Error
  • @IronFist 确实如此。不过,就目前而言,内存/效率对我来说不是问题。我的工作是压缩程序。感谢您指出这一点。

标签: python generator permutation itertools


【解决方案1】:

你已经很接近了,你需要itertools.chain 来“连接”几个迭代器,比如:

alphabet = "ab"

for x in itertools.imap(''.join, itertools.chain(
          *(itertools.product(alphabet, repeat=i)
            for i in range(1,9)))):
    print x

请注意,chain 需要一个参数列表,因此我将 varargs 与生成器表达式一起使用。

编辑:使用来自 cmets 的 itertools.chain.from_iterable

from itertools import chain, imap, product

alphabet = "ab"

for x in imap(''.join, chain.from_iterable(product(alphabet, repeat=i)
                             for i in range(1,9))):
    print x

【讨论】:

  • 还有chain.from_iterable,在输入迭代器数量无限大的情况下特别有用。
【解决方案2】:

如果你想跳出多个循环,你可以使用“return”而不是“break”

【讨论】:

  • 这应该作为评论而不是回答发布,因为它不回答 OP 要求...
  • 我无法发表评论,因为我需要 50 声望才能这样做。我只能评论我自己的问题和答案,但你是对的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 2019-07-15
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多