[英]Print all possible combination of words of length 10 from a list letters with repeating 'A' exactly twice
I have a list of 5 letters ['A', 'B', 'N', 'M','E'].我有一个包含 5 个字母的列表 ['A'、'B'、'N'、'M'、'E']。
I want to print all the words (word means a sequence of letters, it doesn't have to be a valid English word) of length 10 letters that have exactly two letters A. Order is important.我想打印长度为 10 个字母且正好有两个字母 A 的所有单词(单词表示字母序列,它不必是有效的英文单词) 。顺序很重要。
I have tried with itertools.product as it appeared to be the most promising solution:我尝试过使用 itertools.product ,因为它似乎是最有希望的解决方案:
from itertools import product
letters = ['A', 'B', 'N', 'M','E']
for word in product(letters, repeat=10):
res = ''.join(str(x) for x in word)
print(res)
The problem with this approach is that I can't really control the number of occurrences of the letter A as it returns the word composed of 10 letters of A.这种方法的问题是我无法真正控制字母 A 的出现次数,因为它返回由 A 的 10 个字母组成的单词。
Is there a solution for this?有解决方案吗? Thanks谢谢
EDIT 1 Example of possible words: BANAMEMNEB: it has only twice the letter A, we don't care about other letters.编辑 1可能单词的示例: BANAMEMNEB:它只有字母 A 的两倍,我们不关心其他字母。
The way to do it efficiently is to iterate over all combinations of the positions of the letters 'A', and for each such combination - iterate over all the ways other letters can be positioned, and just insert the 'A's there.有效地做到这一点的方法是遍历字母“A”位置的所有组合,并且对于每个这样的组合 - 遍历其他字母可以定位的所有方式,然后在其中插入“A”。
Be warned that with your inputs this will produce almost 3 million words!请注意,您的输入将产生近 300 万字!
On my machine it was printing the words for so long that I had to manually stop execution.在我的机器上,它打印了很长时间的文字,以至于我不得不手动停止执行。
So here is the smaller example:所以这是一个较小的例子:
letters = ['A', 'b', 'c']
num_As = 2
num_total = 4
from itertools import combinations, product
for indices_A in combinations(range(num_total), num_As):
for rest in product(letters[1:], repeat=num_total - num_As):
rest = list(rest)
for index_A in indices_A:
rest.insert(index_A, 'A')
print(''.join(rest))
AAbb
AAbc
AAcb
AAcc
AbAb
AbAc
AcAb
AcAc
AbbA
AbcA
AcbA
AccA
bAAb
bAAc
cAAb
cAAc
bAbA
bAcA
cAbA
cAcA
bbAA
bcAA
cbAA
ccAA
This is basically @Vladimir-Fokow's answer translated to your use case:这基本上是将@Vladimir-Fokow 的答案翻译为您的用例:
#!/usr/bin/env python
from itertools import combinations, product
letters = ['A', 'B', 'N', 'M','E']
first, rest = letters[0], letters[1:]
total_length = 10
first_count = 2
for others in product(rest, repeat=total_length - first_count):
for indices in combinations(range(total_length),first_count):
result = list(others)
for i in indices:
result.insert(i,first)
print(''.join(result))
On my iMac this only took about 3 seconds to print out all 2,949,120 words.在我的 iMac 上,打印所有 2,949,120 个单词只需要大约 3 秒。
A solution would be to filter out the words that do not contain exactly two 'A', as in the following simple code:一个解决方案是过滤掉不包含两个“A”的单词,如下面的简单代码所示:
from itertools import product
from collections import Counter
letters = ['A', 'B', 'N', 'M','E']
for word in product(letters, repeat=10):
res = ''.join(word) # equivalent to res = ''.join(str(x) for x in word) !
ctr = Counter(res)
if ctr['A'] == 2:
print(res)
This can also be written with one-line style coding, as follows:这也可以用单行代码编写,如下所示:
res = [''.join(w) for w in product(letters, repeat=10) if Counter(w)['A'] == 2]
First determine the two indices where the letter "A" will occur, then produce the letters at the other 8 indices:首先确定将出现字母“A”的两个索引,然后在其他 8 个索引处生成字母:
from itertools import combinations, product
def solve():
for i, j in combinations(range(10), 2):
for b in map(list, product("BNME", repeat=8)):
b.insert(i, "A")
b.insert(j, "A")
yield "".join(b)
To print:打印:
for s in solve():
print(s)
...but don't wait for it. ...但不要等待它。 There are 9*10/2 * 4 8 possible combinations, which is almost 3 million.有9*10/2*4 8种可能的组合,差不多300万。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.