Quiero un programa que escriba cada combinación posible en una línea diferente de un archivo de texto

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

  •  04-07-2019
  •  | 
  •  

Pregunta

Quiero escribir un programa que imprima cada combinación de un conjunto de variables en un archivo de texto, creando una lista de palabras. Cada respuesta debe escribirse en una línea separada y escribir todos los resultados de 1 dígito, 2 dígitos y 3 dígitos en un solo archivo de texto.

¿Existe una forma sencilla en la que pueda escribir un programa de python que pueda lograr esto? Este es un ejemplo de la salida que espero al imprimir todas las combinaciones de números binarios posibles para 1, 2 y 3 dígitos:

Output:
0  
1

00  
01  
10  
11

000  
001  
010  
011  
100  
101  
110  
111
¿Fue útil?

Solución

Una solución ingenua que resuelve el problema y es lo suficientemente general para cualquier aplicación que pueda tener es esta:

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

Básicamente, esto construye gradualmente un árbol en la memoria de todas las combinaciones, y luego las devuelve. Sin embargo, requiere mucha memoria y, por lo tanto, no es práctico para combinaciones a gran escala.

Otra solución para el problema es, de hecho, usar el conteo, pero luego transformar los números generados en una lista de palabras de la lista de palabras. Para hacerlo, primero necesitamos una función (llamada 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]

Este es, de hecho, un sistema para convertir números decimales a otras bases. Luego escribimos la función de conteo; esto es relativamente simple y constituirá el núcleo de la aplicación:

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 es un generador de Python; Haciéndolo un generador le permite usar menos RAM. Hay un poco de trabajo por hacer después de convertir el número en una lista de palabras; esto se debe a que estas listas necesitarán relleno para que estén en la longitud solicitada. Sería usado así:

>>> 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 puedes ver, recuperas una lista de listas. Cada una de estas sub-listas contiene una secuencia de las palabras originales; luego puede hacer algo como map (''. join, list (combinaciones ('01 ', 3))) para obtener el siguiente resultado:

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

Entonces podrías escribir esto en el disco; Sin embargo, una idea mejor sería utilizar las optimizaciones integradas que tienen los generadores y hacer algo como esto:

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

Esto solo usará tanta RAM como sea necesario (suficiente para almacenar una combinación). Espero que esto ayude.

Otros consejos

# 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

No debería ser demasiado difícil en la mayoría de los idiomas. ¿Ayuda el siguiente pseudocódigo?

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

A continuación se muestra una función básica para producir todas las permutaciones de una lista. En este enfoque, las permutaciones se crean perezosamente mediante el uso de generadores.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top