在python中生成一个字母?

时间:2014-05-06 15:56:45

标签: python

如何编写一个函数(生成器),它包含三个字母(l1l2l3)和三个数字(n1n2n3)并提供l1出现n1次,l2 n2次和l3 n3的所有可能组合倍。

例如:

for i in function('a', 2, 'b', 1, 'c', 0):
    print(i)

给出:

aab
baa
aba 

4 个答案:

答案 0 :(得分:2)

使用itertools.permutations,您只需要一个薄的包装器:

from itertools import permutations

def l_n_times(l1, n1, l2, n2, l3, n3):
    return permutations(l1*n1 + l2*n2 + l3*n3)

演示:

>>> for item in set(l_n_times('a', 2, 'b', 1, 'c', 0)):
...     print(''.join(item))
...

baa
aba
aab

permutations已经返回了一个生成器,因此您自己没有使用yield

答案 1 :(得分:1)

在我看来itertools在这里不会有太大帮助,尽管递归实现可能如下所示:

def combine(l1, n1, l2, n2, l3, n3):
    counters = {l1: n1, l2: n2, l3: n3}  # remaining characters to use
    buf = []                             # string under construction
    def recur(depth):
        if not depth:  # we've reached the bottom
            yield ''.join(buf)
            return
        # choosing next character
        for s, c in counters.iteritems():
            if not c:  # this character is exhausted 
                continue
            counters[s] -= 1
            buf.append(s)
            for val in recur(depth-1):
                # going down recursively
                yield val

            # restore the state before trying next character
            buf.pop()
            counters[s] += 1

    length = sum(counters.values())
    return recur(length)

for s in combine('a', 2, 'b', 1, 'c', 0):
    print s

答案 2 :(得分:0)

让我们承认您的数据结构如下:

letters = {'a': 2, 'b': 1, 'c': 0}

递归函数将是:

def r(letters, prefix = ''):
    for k,v in letters.items():
        if v > 0:
            d = dict(letters)
            d[k] = v - 1
            for val in r(d, prefix + k):
                yield val
    if all(v == 0 for _, v in letters.items()):
        yield prefix

没有重复,它确实使用了生成器。与简单的itertools调用相比,相当沉重。

答案 3 :(得分:0)

itertools的文档可以这样说;

  

combination()的代码也可以表示为在过滤条目之后排列()的子序列,其中元素不按排序顺序(根据它们在输入池中的位置):

由于我们希望所有组合都没有重复,我们只会强制执行严格的排序(即目前只有屈服值大于最大值);

这似乎就是这样;

def dfunc(l,n):
  old=[]
  for i in it.permutations(''.join(list(a*b for a,b in sorted(it.izip(l,n))))):
    if i > old:
      old=i
      yield i

>>> dfunc(['b','c','a'],[1,0,2])
<generator object dfunc at 0x10ba055a0>

>>> list(dfunc(['b','c','a'],[1,0,2]))
[('a', 'a', 'b'), ('a', 'b', 'a'), ('b', 'a', 'a')]