简体   繁体   English

Python 2.7:在一行代码中迭代字符串的所有组合

[英]Python 2.7: iterate over all combinations of a string in one line of code

I am trying to iterate through all possible combinations of a string between lengths 1 to 8 (inclusive). 我正在尝试遍历长度在1到8(含)之间的string所有可能组合。 My main goal is to have the code in as few lines as possible. 我的主要目标是使代码尽可能地少行。 To do this, I'm currently using Python's itertools library: 为此,我目前正在使用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

I want to be able to do the iterating in one line, so I can break out of the inner and outer for loops at once, and won't need the else: , continue , break etc. Something like this: (using nested for loops) 我希望能够做迭代在同一行,这样我就可以break了内部和外部的for一次循环,将不需要的else:continuebreak这样的东西等(使用嵌套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

However, x turns out to be an <itertools.imap object> . 但是, x原来是<itertools.imap object> So I tried to iterate over x , using more nested for loops (because if I used inner for loops, I will have to break multiple times again): 因此,我尝试使用更多的嵌套for循环遍历x (因为如果使用inner 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

Unfortunately, that still doesn't work; 不幸的是,那仍然行不通。 y is somehow still an <itertools.imap object> . y仍然是<itertools.imap object> I am a self-learned Python programmer, and generators , iterables etc. are confusing me sometimes. 我是一个自学的Python程序员, generatorsiterables等有时使我感到困惑。 Can somebody please help me get the iterating down to one line? 有人可以帮我把迭代简化到一行吗? Thank you so much. 非常感谢。

You are pretty close, you need itertools.chain to "contatenate" several iterators like: 您非常接近,需要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

Note that chain takes a list of arguments, so I'm using varargs with a generator expression. 请注意,chain需要一个参数列表,因此我将varargs与生成器表达式一起使用。

EDIT: Using the itertools.chain.from_iterable from comments: 编辑:从评论中使用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

如果要中断多个循环,可以使用“返回”代替“中断”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM