Я хочу написать простой текстовый классификатор по языкам, используя уникальные буквы, просто для эксперимента.
Например, у меня есть alphabet для каждого языка в качестве набора множеств со следующими ключами: ['ru', 'uk', 'pl', 'en', 'de', 'be', ...]. Например, уникальные польские буквы - это «ę» и «ś», в английском нет уникальных букв. На самом деле, я должен найти все буквы, которые не принадлежат другим языкам. Я сделал это так (простой пример):

alphabets = {'it': {'a', 'b', 'c', 'd', 'e', 'à', 'ì'},
             'en': {'a', 'b', 'c', 'd', 'e'},
             'pl': {'a', 'b', 'c', 'd', 'e', 'ę', 'ś'}}

def union_others(except_lang):
    res = set()
    for lang in alphabets:    
        if lang != except_lang:
            res = res | alphabets[lang]
   return res

unique = {lang: set() for lang in alphabets}
for lang in alphabets:
    unique[lang] = alphabets[lang] - union_others(lang)

print(unique['pl'])

Я получаю следующий вывод: {'ę', 'ś'}

Есть ли простой способ (без цикла) получить объединение всех наборов языков, кроме текущего, вместо использования функции union_others(lang)?

3
Moris Huxley 28 Фев 2018 в 18:31

3 ответа

Лучший ответ

Возможно, вы не сможете полностью уйти от цикла, но вы можете сделать его немного более эффективным, используя короткое замыкание. В большинстве случаев языки не будут иметь действительно уникальных символов, поэтому вы можете выйти из цикла раньше, эффективно избегая создания полного набора других языков каждый раз:

def delta(lang):
    d = set(alphabets[lang]) # make a copy
    for key, alphabet in alphabets.items():
        if key == lang:
            continue
        d -= alphabet
        if not d:
            break
    return d

unique = {lang: delta(lang) for lang in alphabets}

IDEOne Ссылка

Это будет немного быстрее, потому что в наборе, из которого вы вычитаете, почти сразу меньше элементов, что еще больше ускоряет разностную операцию.

Теперь, если у вас есть некоторые априорные знания о сходстве языков, вы можете использовать его для предварительной сортировки alphabets для каждого языка, так что его уникальный набор будет практически сразу сведен к минимуму.

1
Mad Physicist 28 Фев 2018 в 16:35

Вы можете создать набор, который является комбинацией всех языков.

Тогда вы могли бы получить различия между этим большим набором и английским набором, чтобы получить уникальные значения.

Конечно, вам понадобится какой-то итерационный метод для создания большого набора.

РЕДАКТИРОВАТЬ: Это предполагает, что язык, который вы хотите исключить, это английский. Если это другой язык, то вам нужно узнать разницу между большим набором и набором вашего языка. Если вы хотите, чтобы все языки, то вы должны следовать этому процессу для каждого языка и цикл по языкам.

-1
Adi219 28 Фев 2018 в 15:46

Список понятий.

alphabets = {'it': {'a', 'b', 'c', 'd', 'e', 'à', 'ì'},
             'en': {'a', 'b', 'c', 'd', 'e'},
             'pl': {'a', 'b', 'c', 'd', 'e', 'ę', 'ś'}}

def f(k, d):
    #return [x for x in d[k] if any(x not in v for k,v in d.items())]
    return {x for x in d[k] if any(x not in v for k,v in d.items())}


print(f('pl', alphabets))
print(f('en', alphabets))
print(f('it', alphabets))
1
Işık Kaplan 28 Фев 2018 в 15:45