Devo filtrare le stringhe in base al criterio che non contengano il carattere due volte.Qual è il modo più veloce per verificare se una stringa contiene caratteri ripetuti in Python 3?
- Le stringhe sono molti (diciamo 1.400 miliardi).
- Le stringhe sono breve (circa 8 caratteri).
- Le stringhe sono univoche (il caching non funzionerà).
- Le stringhe hanno un set di caratteri grandi (ad esempio qualsiasi carattere Unicode).
- Le stringhe di solito soddisfano il criterio (ad esempio 2/3 non hanno caratteri ripetuti).
Il codice usando sarebbe simile a questa:
>>> candidate_strings = ["foobnehg", "barfnehg", "bazfnehg"]
>>> result_strings = [s if unique_chars(s) for s in candidate_strings]
>>> print(result_strings)
["barfnehg", "bazfnehg"]
ho implementato una versione ingenua, semplicemente scorrendo la stringa:
def unique_chars_naive(string_given):
"""
Checks if a given string contains only unique characters.
This version iterates the given string, saving all occurred characters.
"""
chars_seen = []
for char in string_given:
if char in chars_seen:
return False
chars_seen.append(char)
return True
Il mio prossimo best-idea era quella di utilizzare un set
, quindi l'ho implementato:
def unique_chars_set(string_given):
"""
Checks if a given string contains only unique characters.
This version exploits that a set contains only unique entries.
"""
return len(string_given) == len(set(string_given))
Salvataggio delle funzioni in un file UniqueCharacters.py
, li cronometrato:
$ python3 -m timeit -n 100000 --setup='import UniqueCharacters; candidate_strings = ["foobnehg", "barfnehg", "bazfnehg"]' '[UniqueCharacters.unique_chars_naive(s) for s in candidate_strings]'
100000 loops, best of 3: 20.3 usec per loop
$ python3 -m timeit -n 100000 --setup='import UniqueCharacters; candidate_strings = ["foobnehg", "barfnehg", "bazfnehg"]' '[UniqueCharacters.unique_chars_set(s) for s in candidate_strings]'
100000 loops, best of 3: 17.7 usec per loop
Questo dimostra che il unique_chars_set
è più veloce di circa il 15% di questo insieme di dati.
C'è un modo più veloce per farlo? Con le espressioni regolari forse? C'è qualche metodo nella libreria standard che lo fa?
Potrebbero esserci stringhe ripetute in 'candidate_strings'? – Jared
Test con parole più lunghe. –
Tutte le stringhe contengono solo caratteri alfabetici minuscoli? In caso contrario, contengono solo caratteri ASCII? – Kevin