Voglio un programma che scriva ogni possibile combinazione su una diversa riga di un file di testo

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

  •  04-07-2019
  •  | 
  •  

Domanda

Voglio scrivere un programma che stampi ogni combinazione di un insieme di variabili in un file di testo, creando un elenco di parole. Ogni risposta deve essere scritta su una riga separata e scrivere tutti i risultati per 1 cifra, 2 cifre e 3 cifre in un singolo file di testo.

Esiste un modo semplice per scrivere un programma Python in grado di farlo? Ecco un esempio dell'output che mi aspetto quando stampo tutte le combinazioni di numeri binari possibili per 1, 2 e 3 cifre:

Output:
0  
1

00  
01  
10  
11

000  
001  
010  
011  
100  
101  
110  
111
È stato utile?

Soluzione

Una soluzione na che risolve il problema ed è abbastanza generale per qualsiasi applicazione che potresti avere è questa:

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

Fondamentalmente, questo crea gradualmente un albero in memoria di tutte le combinazioni, e poi le restituisce. È ad alta intensità di memoria, tuttavia, e non è pratico per combinazioni su larga scala.

Un'altra soluzione al problema è, in effetti, usare il conteggio, ma poi trasformare i numeri generati in un elenco di parole dall'elenco di parole. Per fare ciò, abbiamo prima bisogno di una funzione (chiamata 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]

Questo è, in effetti, un sistema per convertire numeri decimali in altre basi. Quindi scriviamo la funzione di conteggio; questo è relativamente semplice e costituirà il nucleo dell'applicazione:

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

Questo è un generatore Python; rendendolo un generatore gli consente di utilizzare meno RAM. C'è un po 'di lavoro da fare dopo aver trasformato il numero in un elenco di parole; questo perché questi elenchi dovranno essere riempiti in modo che siano alla lunghezza richiesta. Sarebbe usato in questo modo:

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

Come puoi vedere, ritorni un elenco di liste. Ciascuno di questi elenchi secondari contiene una sequenza delle parole originali; potresti quindi fare qualcosa come map (''. join, list (combinazioni ('01 ', 3))) per recuperare il seguente risultato:

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

Potresti quindi scrivere questo su disco; un'idea migliore, tuttavia, sarebbe quella di utilizzare le ottimizzazioni integrate dei generatori e fare qualcosa del genere:

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

Questo utilizzerà solo la quantità di RAM necessaria (sufficiente per memorizzare una combinazione). Spero che questo aiuti.

Altri suggerimenti

# 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

Non dovrebbe essere troppo difficile nella maggior parte delle lingue. Il seguente pseudo-codice aiuta?

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

Di seguito viene fornita una funzione di base per produrre tutte le permutazioni di un elenco. In questo approccio, le permutazioni vengono create pigramente usando i generatori.

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top