[英]Create all possible dictionary-based words from a set of letters - Tips to improve processing speed
我有一個小項目,我必須解讀(找到所有可能只用一組字母中的一個字母才能寫的單詞)100 000個字母集,每個字母集包含12個字母。 我想找到在Python中處理此任務的速度方面的最佳方法。 到目前為止,我已經花了10個小時,但是命令尚未完成運行。
我看過其他帖子中的確切問題,並從itertools中看到了排列方法。 我認為這比我從網站(以下代碼)借用的這種方法要慢得多。 實際上,對12個字母的字母集進行一次排列已為我的筆記本電腦花費了大量時間。 也許我誤會了一些東西。
我正在使用的字典是西班牙語。 出於演示目的,我將字母集生成為1個字符串,而不是列表。
letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','ñ','o','p','q','r','s','t','u','v','w','x','y','z','á','é','í','ó','ú','ü']
def randomString(stringLength=12):
"""Generate a random string of fixed length """
return ''.join(random.choice(letters) for i in range(stringLength))
定義解密功能
def charCount(word):
dict = {}
for i in word:
dict[i] = dict.get(i, 0) + 1
return dict
def possible_words(vocab, letterset):
unscrambled_words = []
for word in vocab:
flag = 1
chars = charCount(word)
for key in chars:
if key not in letterset:
flag = 0
else:
if letterset.count(key) != chars[key]:
flag = 0
if flag == 1:
unscrambled_words.append(word)
return unscrambled_words
vocab:是一本字典,包含約170 000個單詞。 我把這些詞放在Python列表中。
letteret:是字母列表。 例如:['x','d','a','a','o','u','e','g','g','m','n','f “]。
以下代碼運行了10個小時,但尚未完成。 在我輸入此信息時,它仍在運行。
unscrambled_list = []
for i in range(0,100000):
possib_words = possible_words(es_vocab,list(letterset_list[i]))
unscrambled_list.append(possib_words)
詞匯詞典示例: es_vocab = ['ame', 'amo', 'año', 'apio', 'ema', 'empaño', 'me', 'mi', 'miope', 'opima', 'paño', 'pe', 'peña', 'pi', 'pia', 'pie', 'piña', 'pio', 'poema', 'a', 'o', 'e', 'xl', 'kl', 'ml']
#最后3個值不是實際單詞
示例字母集:
letterset_list = ['oiwóeaópñmóó']
如果有人向我展示了完成此任務的更快方法,那就太好了!
es_vocab = ['ame', 'amo', 'año', 'apio', 'ema', 'empaño', 'me', 'mi', 'miope', 'opima', 'paño', 'pe', 'peña', 'pi', 'pia', 'pie', 'piña', 'pio', 'poema', 'a', 'o', 'e', 'xl', 'kl', 'ml']
from itertools import combinations
def generate_key(w):
out = []
for ch in set(w):
out.append( (ch, w.count(ch)) )
return out
#build index
index = {}
for word in es_vocab:
index.setdefault(frozenset(generate_key(word)), []).append(word)
letterset_list = ['oiwóeaópñmóó']
seen_substrings = set()
for x in letterset_list:
all_substrings = (''.join(l) for i in range(len(x)) for l in combinations(x, i+1))
for substring in all_substrings:
substring = ''.join(sorted(substring))
if substring in seen_substrings:
continue
seen_substrings.add(substring)
key = frozenset(generate_key(substring))
if not key in index:
continue
for word in index[key]:
print(word)
打印:
o
e
a
pi
mi
pe
me
pio
año
amo
pie
pia
ame
ema
apio
paño
piña
peña
miope
opima
poema
empaño
編輯:生成100_000 lettersets和檢查他們反對es_vocab
把我的機器上:
real 10m42,351s
user 10m38,069s
sys 0m3,854s
編輯2:現在可以正確處理帶有重復字母的單詞。
def charCount(s):
s = s.lower()
answer = [0]*26
for char in s: answer[ord(char)-97] += 1
return tuple(answer)
def preprocess(vocab):
answer = collections.defaultdict(list)
for word in vocab: answer[charCount(word)].append(word)
return answer
def possible_words(vocab, scrambled):
'''note that the `vocab` parameter is actually intended to be preceprocess(list_of_dictionary_words)'''
return vocab[charCount(scrambled)]
def get_all_possible_words(vocab, lettersets):
vocab = preprocess(vocab)
answer = {}
for letterset in lettersets:
answer[tuple(letterset)] = possible_words(vocab, letterset)
return answer
我可能會這樣處理:
def contains_word(letters, word):
return all(char in letters for char in word)
並確保letters
是一set
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.