나는 가능한 모든 조합을 다른 줄의 텍스트 파일에 쓰는 프로그램을 원한다.
문제
변수 세트의 모든 조합을 텍스트 파일에 인쇄하여 단어 목록을 작성하는 프로그램을 작성하고 싶습니다. 각 답변은 별도의 줄에 작성되어야하며 1 자리, 2 자리 및 3 자리에 대한 모든 결과를 단일 텍스트 파일에 작성해야합니다.
이것을 달성 할 수있는 파이썬 프로그램을 작성할 수있는 간단한 방법이 있습니까? 다음은 1, 2 및 3 자리에 가능한 모든 이진 번호 조합을 인쇄 할 때 기대하는 출력의 예입니다.
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
기본적으로 이것은 점차적으로 모든 조합을 기억하여 나무를 쌓고 반환합니다. 그러나 메모리 집약적이지만 대규모 조합에는 실용적이지 않습니다.
문제에 대한 또 다른 해결책은 실제로 계산을 사용하는 것이지만 생성 된 숫자를 워드리스트의 단어 목록으로 변환하는 것입니다. 그렇게하려면 먼저 함수가 필요합니다 ( 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]
이것은 실제로 소수점을 다른베이스로 변환하는 시스템입니다. 그런 다음 계산 기능을 작성합니다. 이것은 비교적 간단하며 응용 프로그램의 핵심을 구성합니다.
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
이것은 파이썬 생성기입니다. 발전기로 만들면 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 만 사용합니다 (하나의 조합을 저장하기에 충분). 이게 도움이 되길 바란다.
다른 팁
# 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