Сортировать кириллицу c строк перед латиницей в python - PullRequest
4 голосов
/ 05 марта 2020

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

ab c ... bcd ... cde ... абв ...

I хотел бы поставить кириллицу c на первое место:

абв ... ab c ... bcd ... cde ...

Что я пробовал до сих пор:

  1. Это решение . Это не так здорово, потому что сортирует только по первому слову, и у меня могут быть кириллические c и латинские слова в одной строке (или даже смешанные символы в одном и том же слове).

  2. Написание собственных списков с кириллицей c и латинскими алфавитами. Это работает, но не очень хорошо. Я не могу учесть все возможные буквы в двух алфавитах, в том числе с диакритическими знаками, и записать их.

Я также изучал PyICU, но не вижу, как я могу поставить это использовать.

Я предполагаю, что я должен использовать некоторые пользовательские сопоставления здесь. Вопрос в том, как это можно сделать на практике.

Ответы [ 3 ]

2 голосов
/ 05 марта 2020

Один из способов сделать это - использовать transliterate модуль или, возможно, cytranslit и использовать ключ сортировки, который транслитерирует все в нужный алфавит:

import transliterate

items = ['abc', 'bcd', 'cde', 'абв']

print(sorted(items, key=lambda x: transliterate.translit(x, 'ru')))

Выход желаемый

['абв', 'abc', 'bcd', 'cde']
1 голос
/ 05 марта 2020

ИМО это не тривиальная вещь. Я бы сказал, что сопоставление действительно требуется.

Итак, скажем, ключевая функция преобразует строку в кортеж кодовых точек, где все не-кириллические c кодовые точки будут сдвинуты на 100000):

import unicodedata

def key(s):
    SHIFT = 100000
    return tuple(
        ord(c) if is_cyrillic(c) else ord(c) + SHIFT
        for c in s
    )

def is_cyrillic(c):
    return unicodedata.name(c).startswith('CYRILLIC')        


>>> sorted(('wannt', 'waюnnt'), key=key)
Out[34]: ['waюnnt', 'wannt']

is_cyrillic можно оптимизировать с помощью предварительной таблицы или кэширования символов кириллицы c из строк базы данных.

0 голосов
/ 05 марта 2020

Вы можете попытаться сгенерировать ключ, добавив перед каждым символом 1, если это латинский символ, и 0 в противном случае:

sorted(items, key = lambda item : ['1' + x if x < '\x7f' else '0' + x for x in item])
...