2012-03-16 20 views
5

Provare a scrivere una funzione for che prende due stringhe e restituisce i caratteri che si intersecano nell'ordine in cui appaiono nella prima stringa.Python - Stringhe di intersecazione

Ecco cosa ho provato:

def strIntersection(str1, str2): 
    for i in str1: 
     str3 = '' 
     str3 = str3.join(i for i in str1 if i in str2 not in str3) 
    return str3 

str1 = 'asdfasdfasfd' 
str2 = 'qazwsxedc' 

strIntersection(str1,str2) 

=> 'asdasdasd' 

però voglio solo i personaggi di intersezione di apparire una volta e in ordine di prima stringa es. 'asd'

Qualcuno può aiutare?

ho trovato alcuni problemi simili su altri forum ma le soluzioni sembrano tutte a coinvolgere le liste, mentre mi piacerebbe la mia uscita di essere una stringa

risposta

6

Verificare la presenza di occorrenze il contrario per ottenere l'ordine sotto controllo, e non emettere caratteri che hai già emesso:

def strIntersection(s1, s2): 
    out = "" 
    for c in s1: 
    if c in s2 and not c in out: 
     out += c 
    return out 

Sicuro che co ri-scriverlo per essere una lista di comprensione, ma trovo questo più facile da capire.

Per i vostri dati di test, otteniamo:

>>> strIntersection('asdfasdfasfd' , 'qazwsxedc') 
'asd' 
+0

Grazie! È certamente più facile da capire. Ora mi rendo conto che l'ho complicato cercando di usare '' join() – bang

+0

''.' .join' è idiomatico e non è affatto complicato. Usarlo in un ciclo, tuttavia, manca il punto. In realtà, il ciclo for nel codice OP è completamente inutile; semplicemente fa sì che il vero lavoro - 'str3 = str3.join (io per i in str1 se io in str2 non in str3)' sia eseguito più volte, con lo stesso risultato ogni volta, e il risultato sia gettato via ogni volta ma l'ultimo. –

+0

Non si può realmente riscrivere questo particolare algoritmo per essere una lista di comprensione - almeno non senza invocare alcune cose non documentate molto discutibili - perché il passo di filtraggio 'c in s2 e c non in out' dipende dai risultati parziali fino a questo punto , che non sono resi accessibili (eccetto che per cose non documentate molto dubbie). –

7

Volete una stringa costituita dai caratteri unici che sono comuni a str1 e str2, nell'ordine in cui appaiono in str1.

Unicità e commonness implicano operazioni di set: ovvero, stiamo cercando il set di caratteri che compaiono sia in str1 che in str2. Un set è fondamentalmente non ordinato, ma possiamo riordinare i dati ordinando i caratteri in base al loro "indice" di prima occorrenza in str1. Quindi si tratta semplicemente di creare una stringa dalla sequenza ordinata.

Mettere tutto insieme, otteniamo:

''.join(sorted(set(str1) & set(str2), key = str1.index)) 
0

Sembra che lo script corrente dovrebbe farlo se si fissa l'errore di battitura sulla quarta riga:

str3 = str3.join(i for i in str1 if i in str2 not in str3) 

dovrebbe essere

str3 = str3.join(i for i in str1 if i in str2 and i not in str3) 

Non consiglierei di utilizzare un set per questo semplice perché non garantiscono l'ordine. È probabile che anche lo script sia più veloce.

+0

Sono abbastanza sicuro di quale OP intendesse effettivamente fosse '(io per i in str1 se io in str2 e non in str3)'. Tranne che questo non funziona perché il 'str3' che deve essere confrontato contro non è stato ancora costruito. Ha confuso la sua logica tentando di usare sia il ciclo for che la comprensione. Per quanto riguarda le prestazioni, mi aspetto che gli approcci basati su 'set' siano molto più veloci per le stringhe lunghe. –

+0

@Karl: Sì hai ragione, aggiornerò la mia risposta. Ma il confronto con str3 non dovrebbe essere un problema in quanto deve solo controllare la parte che è già stata costruita. – aquavitae

+0

Il problema è che 'str3' ** non è **" la parte che è già stata costruita ". O esegui questo codice in un ciclo o non lo fai. Se non lo fai, allora 'str3' darà un UnboundLocalError - stai cercando di riferirti alla cosa a cui stai assegnando. Se lo fai, allora hai un 'join' e una comprensione non ha senso, dal momento che vuoi solo considerare il personaggio attuale rispetto ai caratteri intersecanti già trovati, non l'intera stringa. –

0
def str_intersection(str1, str2): 
    common_letters = set(str1) & set(str2) 
    str3 = '' 
    for c in str1: 
     if (c in common_letters) and (c not in str3): 
      str3 += c 
    return str3 
1

semplice è quello di utilizzare i set in python

>>> a='asdfasdfasfd' 
>>> b='qazwsxedc' 
>>> set(a).intersection(b) 
set(['a', 's', 'd']) 
+0

Questo replica le risposte esistenti e non fornisce l'ordinamento richiesto da OP. –

Problemi correlati