Eu quero um programa que escreve todas as combinações possíveis para uma linha diferente de um arquivo de texto

StackOverflow https://stackoverflow.com/questions/241533

  •  04-07-2019
  •  | 
  •  

Pergunta

Eu quero escrever um programa que iria imprimir cada combinação de um conjunto de variáveis ??para um arquivo de texto, criando uma lista de palavras. Cada resposta deve ser escrito em uma linha separada e escrever todos os resultados para 1 dígito, 2 dígitos, e 3 dígitos para um único arquivo de texto.

Existe uma simples maneira que eu posso escrever um programa python que pode fazer isso? Aqui está um exemplo da saída Estou esperando ao imprimir todas as combinações de números binários possível para 1, 2 e 3 dígitos:

Output:
0  
1

00  
01  
10  
11

000  
001  
010  
011  
100  
101  
110  
111
Foi útil?

Solução

Uma solução ingênua que resolve o problema e é bastante geral para qualquer aplicação que você pode ter é a seguinte:

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

Basicamente, esta gradualmente se acumula uma árvore em memória de todas as combinações, e, em seguida, retorna-los. É muita memória, no entanto, e por isso é impraticável para combinações de grande escala.

Outra solução para o problema é, na verdade, para usar a contagem, mas, em seguida, para transformar os números gerados em uma lista de palavras da lista de palavras. Para isso, primeiro precisamos de uma função (chamada 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]

Esta é, de fato, um sistema para converter números decimais em outras bases. Em seguida, escrever a função de contagem; isso é relativamente simples, e irá tornar-se o núcleo do aplicativo:

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

Este é um gerador de Python; tornando-se um gerador lhe permite usar até menos RAM. Há um pouco de trabalho para ser feito depois de completar o número em uma lista de palavras; Isso ocorre porque essas listas terão preenchimento de modo que eles estão no comprimento desejado. Seria usado como este:

>>> 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']]

Como você pode ver, você recebe de volta uma lista de listas. Cada um destes sub-listas contém uma sequência de palavras originais; que você pode então fazer algo parecido map(''.join, list(combinations('01', 3))) para recuperar o seguinte resultado:

['000', '001', '010', '011', '100', '101', '110', '111']

Você pode então escrever este para o disco; uma idéia melhor, no entanto, seria usar o built-in otimizações que os geradores têm e fazer algo como isto:

fileout = open('filename.txt', 'w')
fileout.writelines(
    ''.join(combo) for combo in combinations('01', 3))
fileout.close()

Isso só vai usar mais memória RAM quanto necessário (o suficiente para armazenar uma combinação). Espero que isso ajude.

Outras dicas

# 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

Não deve ser muito difícil na maioria dos idiomas. Faz o seguinte ajuda pseudo-código?

for(int i=0; i < 2^digits; i++)
{
     WriteLine(ToBinaryString(i));
}

A função básica para produzir todas as permutações de uma lista é dado abaixo. Nesta abordagem, permutações são criados preguiçosamente usando geradores.

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top