【问题标题】:Python Itertools Code OptimisationPython Itertools 代码优化
【发布时间】:2017-11-02 14:49:02
【问题描述】:

鉴于question(比赛现在结束了)

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

鉴于密码的长度,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 ""

有没有更好的方法来做到这一点?

【问题讨论】:

  • 关于改进现有代码的问题属于 Code Review,而不是 Stack Overflow。

标签: python optimization itertools


【解决方案1】:

当然有更好的方法(如果您的意思是更快)。您可以生成一个itertools.product,您不必“丢弃”项目。

您可以简单地创建vowel, consonant, vowel, consonant, ... 的product(交替两个列表n 次)和一个以consonant, vowel, consonant, vowel, ... 开头的列表。返回的项目将始终满足条件,因此只需printing 他们。

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,这意味着:最初从product 生成的9765625 项目(几乎1000 万!)现在只会生成250000 项目。即使忽略(可能非常昂贵)检查您的序列是否满足问题条件(现在已过时),您在 product 中生成的项目数量增加了 40 倍!

【讨论】:

    猜你喜欢
    • 2017-04-06
    • 2017-03-13
    • 2017-09-03
    • 1970-01-01
    • 2014-06-24
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多