2010-06-03 13 views
5

W PHP, miałem tę linię matches = preg_grep('/^for/', array_keys($hash)); Co by to zrobiło, to złapałoby słowa: fork, formularzy itp., Które są w $ hash.Funkcja autouzupełniania z pythoniem Dict

W języku Python mam dykt z 400 000 słów. To klucze to słowa, które chciałbym przedstawić w funkcji automatycznego uzupełniania (wartości w tym przypadku są bez znaczenia). Jak byłbym w stanie zwrócić klucze z mojego słownika, które pasują do danych wejściowych?

Na przykład (jak używany wcześniej), jeśli mam

my_dic = t{"fork" : True, "form" : True, "fold" : True, "fame" : True} 

i ja trochę wejście "for", to będzie zwrócić listę "fork", "form".

+0

'' fold'' nie za dużo '' for'' – SilentGhost

+0

SilentGhost: jesteś absolutnie poprawny, edytowany. – tipu

Odpowiedz

6
>>> mydict={"fork" : True, "form" : True, "fold" : True, "fame" : True} 
>>> [k for k in mydict if k.startswith("for")] 
['fork', 'form'] 

ten powinno być szybsze niż użycie wyrażenia regularnego (i wystarczające, jeśli szukasz tylko początku słów).

1
>>> my_dict = {"fork" : True, "form" : True, "fold" : True, "fame" : True} 
>>> import re 
>>> [s for s in my_dict if re.search('^for', s) is not None] 
['fork', 'form'] 

użycie regex jest bardziej uniwersalna, jak można zapewnić bardziej skomplikowanych wzorów wyszukiwania, jeśli jest to tylko około prefiksów, można użyć metody string: str.startwith, na przykład:

>>> [s for s in my_dict if s.startswith('for')] 
['fork', 'form'] 
0

Możesz dostać klucze z my_dict za pomocą my_dict.keys(). Następnie możesz przeszukać każdy klucz, aby sprawdzić, czy pasuje do Twojego zwykłego wyrażenia.

m = re.compile('^for') 
keys = [] 
for key in my_dict.keys(): 
    if m.match(key) != None: 
     keys.append(key) 
3

Więc nie jest to bezpośrednia odpowiedź na co pytasz, ale ..

Wydaje się, że tak naprawdę nie chcą dict dla tego rodzaju rzeczy, ty szukasz struktura przypominająca drzewo, prawda?

Następnie możesz przejść drzewo dla każdej wpisanej litery (stały czas) i wrócić liście z tej podsekcji drzewa jako słowa pasujące do tego prefiksu.

+0

Ten szczególny przypadek to nie jedyny czas, w którym używam dyktatu. Jest to indeks odwrócony, więc wartości są zbiorem identyfikatorów dokumentów, które są absolutnie niezbędne dla tego, co robię. Powodem, dla którego używam dyktowania, jest to, że wyszukiwanie będzie dużo szybsze niż drzewo (pamięć jest obfitująca, cykle procesora nie są) – tipu

+0

Chociaż wyszukiwanie w znanym kluczu będzie szybsze w przypadku dyktowania niż struktura drzewa, klucz do częściowego dopasowania nie będzie - więc w przypadkach, gdy nie znasz klucza z góry (jak na przykład powyżej), coś trochę bardziej przypominającego drzewo byłoby lepsze. – pycruft

+2

Fyi, idealna struktura danych dla tego problemu nazywa się ** trie ** - ale stdlib Pythona nie ma takiego. –

1

Jeśli chcesz zastosować określoną strategię wyszukiwania (taką jak "startwith 3 chars" opisaną powyżej), prawdopodobnie można uzyskać szybką wygraną, tworząc słownik odnośnika oparty na tym pomyśle.

q = {"fork":1, "form":2, "fold":3, "fame":4} 
from collections import defaultdict 
q1 = defaultdict(dict) 
for k,v in q.items(): 
    q1[k[:3]][k]=v 

Byłoby to niech to zrobić odnośnika .startswith typu na znacznie mniejszy zestaw

def getChoices(frag): 
    d = q1.get(frag[:3]) 
    if d is None: 
     return [] 
    return [ k for k in d.keys() if k.startswith(frag) ] 

miejmy nadzieję, że powinno być o wiele szybciej niż przetwarzanie całych 400.000 klucze.

Powiązane problemy