Python Itertools代码优化

时间:2017-06-01 12:38:59

标签: python optimization itertools

  

鉴于question(比赛 现在 结束)

  • 密码由n小写英文字母组成。
  • 密码是悠扬的,这意味着辅音只能在旁边 元音和元音只能在辅音旁边。示例:bawahaha
  • 密码不能包含字母y(因为它都是a 辅音和元音)。
  • 密码的第一个字母可以是 元音或辅音。

enter image description here

给定密码的长度n

打印符合上述条件的所有可能密码。

输入格式

输入行包含整数(密码长度)。

约束

输出格式

打印每个可能的密码,每行一个。密码的顺序无关紧要。

我的Python代码:

import sys
import itertools

n = int(raw_input().strip())

consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z']
vowels = ['a', 'e', 'i', 'o', 'u']


test4 = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z', 'a', 'e', 'i', 'o', 'u']
answer = set(itertools.product(test4, repeat=n))

for letters in answer:
    for j in xrange(len(letters)):
        flag = 1
        if j != len(letters) - 1:
            if letters[j] in vowels and letters[j+1] in vowels:
                flag = 0
                break
            if letters[j] in consonants and letters[j+1] in consonants:
                flag = 0
                break

    if flag:
        for j in letters:
            sys.stdout.write(j)
        print ""

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

当然,有更好的方法(如果你的意思更快)。您可以生成itertools.product,而不必放弃"丢弃"项目

您只需创建一个product vowel, consonant, vowel, consonant, ...(交替显示两个列表n次)和一个以consonant, vowel, consonant, vowel, ...开头的列表。返回的项目将始终满足条件,因此需要完成的只是print

import itertools

def alternating(seq1, seq2, length):
    """Generator that alternatingly yields seq1 and seq2, `length` times"""
    assert length >= 0
    for _ in range(length // 2):
        yield seq1
        yield seq2
    if length % 2 == 1:
        yield seq1

consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z']
vowels = ['a', 'e', 'i', 'o', 'u']

n = int(raw_input().strip())

# Starts with vowel
for comb in itertools.product(*list(alternating(vowels, consonants, n))):
    print(''.join(comb))

# Starts with consonant
for comb in itertools.product(*list(alternating(consonants, vowels, n))):
    print(''.join(comb))

这样你可以减少可能的候选人数量。

您的方法提供了25**n项,而新方法仅生成2 * 5**(n//2)*20**(n//2)(如果n偶数)或5**(n//2 + 1) * 20 ** (n//2) + 5**(n//2) * 20 ** (n//2 + 1)(如果n奇数)项。

对于n=5,这意味着:9765625生成的原始product项(近1千万!)现在只会生成250000个项目。甚至忽略(可能非常昂贵)检查你的序列是否满足问题条件(现在已经过时),你在product生成了40多个项目!