すべての可能な組み合わせをテキストファイルの異なる行に書き込むプログラムが必要です。
質問
一連の変数のすべての組み合わせをテキストファイルに出力し、単語リストを作成するプログラムを作成したい。各回答は個別の行に記述し、1桁、2桁、3桁のすべての結果を単一のテキストファイルに書き込む必要があります。
これを達成できるpythonプログラムを書く簡単な方法はありますか?以下は、1、2、3桁で可能なすべての2進数の組み合わせを印刷するときに予想される出力の例です。
Output:
0
1
00
01
10
11
000
001
010
011
100
101
110
111
解決
問題を解決し、あらゆるアプリケーションに十分な一般的な解決策は次のとおりです。
def combinations(words, length):
if length == 0:
return []
result = [[word] for word in words]
while length > 1:
new_result = []
for combo in result:
new_result.extend(combo + [word] for word in words)
result = new_result[:]
length -= 1
return result
基本的に、これはすべての組み合わせのメモリに徐々にツリーを構築し、それらを返します。ただし、メモリを大量に消費するため、大規模な組み合わせでは実用的ではありません。
この問題のもう1つの解決策は、実際にはカウントを使用することですが、生成された数値をワードリストから単語のリストに変換することです。そのためには、最初に関数( number_to_list()
と呼ばれる)が必要です:
def number_to_list(number, words):
list_out = []
while number:
list_out = [number % len(words)] + list_out
number = number // len(words)
return [words[n] for n in list_out]
これは実際、10進数を他の基数に変換するシステムです。次に、カウント関数を作成します。これは比較的単純で、アプリケーションの中核を構成します。
def combinations(words, length):
numbers = xrange(len(words)**length)
for number in numbers:
combo = number_to_list(number, words)
if len(combo) < length:
combo = [words[0]] * (length - len(combo)) + combo
yield combo
これはPythonジェネレーターです。ジェネレーターにすると、使用するRAMが少なくなります。数字を単語のリストに変換した後、少し作業が必要です。これは、これらのリストが要求された長さになるようにパディングが必要になるためです。次のように使用されます。
>>> list(combinations('01', 3))
[['0', '0', '0'], ['0', '0', '1'],
['0', '1', '0'], ['0', '1', '1'],
['1', '0', '0'], ['1', '0', '1'],
['1', '1', '0'], ['1', '1', '1']]
ご覧のとおり、リストのリストが返されます。これらの各サブリストには、一連の元の単語が含まれています。次に、 map( ''。join、list(combinations('01 '、3)))
のような操作を行って、次の結果を取得します。
['000', '001', '010', '011', '100', '101', '110', '111']
これをディスクに書き込むことができます。ただし、ジェネレーターが備えている組み込みの最適化を使用して、次のようなことを行うことをお勧めします。
fileout = open('filename.txt', 'w')
fileout.writelines(
''.join(combo) for combo in combinations('01', 3))
fileout.close()
これは、必要なだけのRAMを使用します(1つの組み合わせを保存するのに十分です)。これがお役に立てば幸いです。
他のヒント
# Given two lists of strings, return a list of all ways to concatenate
# one from each.
def combos(xs, ys):
return [x + y for x in xs for y in ys]
digits = ['0', '1']
for c in combos(digits, combos(digits, digits)):
print c
#. 000
#. 001
#. 010
#. 011
#. 100
#. 101
#. 110
#. 111
ほとんどの言語ではそれほど難しくないはずです。次の擬似コードは役立ちますか?
for(int i=0; i < 2^digits; i++)
{
WriteLine(ToBinaryString(i));
}
リストのすべての順列を生成する基本的な関数を以下に示します。このアプローチでは、ジェネレーターを使用して順列が遅延的に作成されます。
def perms(seq):
if seq == []:
yield []
else:
res = []
for index,item in enumerate(seq):
rest = seq[:index] + seq[index+1:]
for restperm in perms(rest):
yield [item] + restperm
alist = [1,1,0]
for permuation in perms(alist):
print permuation