Уведомления

Группа в Telegram: @pythonsu

#1 Май 25, 2015 18:54:45

Pawl
Зарегистрирован: 2015-05-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

FishHook
Да блин! sorted не изменяет исходный список, в вашей интерпретации эта операция бессмысленна.
Хорошо. Пусть такая операция имеет смысл только со списком. Так
from codecs import open
from re import split
text = open("load", "r", "utf-8")
s = text.read()
words = split('[\d\W]+', s)
words.remove('')
ALPHABET = {i[1]: i[0] for i in enumerate(u"абвгдеёжзийклмнопрстуфхцчшщъыьэюя")}
for i in sorted(words, key=lambda x: ALPHABET[x[0].lower()]):
    print(i)
Все слова из файла сортируются прекрасно. Но когда я делаю из сортированного списка словарь:
d = {}
for w in words:
    if w != '':
        if w in d:
            d[w] += 1
        else:
            d[w] = 1
items = list(d.items())
вся сортировка слетает нафиг и потом вот это
for i in items:
    print(i)
Выдаёт, что Бог на душу положит. Можно как-нибудь сделать сортированным не список, а именно словарь?
Иными словами, получается так:
('мёд', 1)
('муляж', 1)
('мороз', 1)
('метёлка', 1)
('ель', 2)
('ёжик', 1)
('ежевика', 3)
('емеля', 1)
('метла', 1)
('улитка', 3)
('ёлка', 3)
а я хочу, чтоб было так:
('ежевика', 3)
('ель', 2)
('емеля', 1)
('ёжик', 1)
('ёлка', 3)
('метёлка', 1)
('метла', 1)
('мёд', 1)
('мороз', 1)
('муляж', 1)
('улитка', 3)
Shaman
е ё ё моё ёжик ежовый ёлочка ель ельник упырь ягель ямка
Ну, тут “ёжик” идет перед “ежовый”, что не корректно, т. к. по алфавиту е идёт перед ё.

Отредактировано Pawl (Май 25, 2015 18:59:25)

Офлайн

#2 Май 25, 2015 19:33:29

MiK
Зарегистрирован: 2014-10-30
Сообщения: 191
Репутация: +  -1  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

Pawl
Словарь это ассоциативный массив, его нельзя сортировать. Чтобы отсортировать словарь, из него нужно получить список и сортировать уже его.

Офлайн

#3 Май 25, 2015 19:38:30

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

lst = [u'ё', u'ель', u'ямка', u'ёлочка', u'упырь', u'ёжик', u'ё моё', u'е',  u'ельник', u'ежовый', u'ягель']
class mytr:
    def __init__(self):
        abet = u' абвгдеёжзийклмнопрстуфхцчшщъыьэюя'
        self.td = {c: k for k, c in enumerate(abet)}
    def __call__(self, s):
        return tuple(self.td[c] for c in s.lower())
lst.sort(key=mytr())
print ' '.join(lst)
е ежовый ель ельник ё ё моё ёжик ёлочка упырь ягель ямка
Как-то так

Отредактировано Shaman (Май 25, 2015 20:31:26)

Офлайн

#4 Май 25, 2015 19:42:48

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

Pawl
Что-то мне подсказывает, что доку по питону вы почитать поленились. Хотя бы основные типы то надо понять: list, dict, set, tuple. Потратьте час времени на изучение этих четырех типов коллекций и станет гораздо проще.



Офлайн

#5 Май 25, 2015 19:51:46

Pawl
Зарегистрирован: 2015-05-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

MiK
Pawl
Словарь это ассоциативный массив, его нельзя сортировать. Чтобы отсортировать словарь, из него нужно получить список и сортировать уже его.
Хорошо, а как мне это сделать? Нашел вариант:
od = collections.OrderedDict(sorted(d.items()))
, скрестил его с примером FishHook'а, получилось, вроде, компактно:
from codecs import open
from re import split
from collections import OrderedDict
text = open("load", "r", "utf-8")
s = text.read()
words = split('[\d\W]+', s)
words.remove('')
d = {}
for w in words:
    if w in d:
        d[w] += 1
    else:
        d[w] = 1
ALPHABET = {i[1]: i[0] for i in enumerate(u"абвгдеёжзийклмнопрстуфхцчшщъыьэюя")}
od = OrderedDict(sorted(d.items(), key=lambda x: ALPHABET[x[0][0].lower()]))
for i in od.items():
    print(i)
но сортирует всё-равно не корректно: только по первым буквам:
('емеля', 1)
('Ель', 1)
('ежевика', 3)
('ель', 2)
('ёжик', 2)
('ёлка', 3)
('Ёжик', 1)
('мороз', 1)
('метёлка', 1)
('метла', 1)
('муляж', 1)
('мёд', 1)
('улитка', 3)
как видно, вторые буквы уже плавают.
Мой вариант работает, но уж очень в нём много букофф:
from codecs import open
from functools import cmp_to_key
from re import split
from collections import OrderedDict
text = open("load", "r", "utf-8")
s = text.read()
words = split('[\d\W]+', s)
words.remove('')
d = {}
for w in words:
    if w in d:
        d[w] += 1
    else:
        d[w] = 1
def comparator(a, b):
    x = str(a)
    y = str(b)
    t = len(x) if len(x) < len(y) else len(y)
    for j in range(t):
        if x[j].lower() == y[j].lower():
            continue
        if x[j].lower() != 'ё' and y[j].lower() != 'ё':
            if x[j].lower() < y[j].lower():
                return -1
            else:
                return 1
        elif x[j].lower() == 'ё':
            if y[j].lower() > 'е':
                return -1
            else:
                return 1
        elif y[j].lower() == 'ё':
            if x[j].lower() > 'е':
                return 1
            else:
                return -1
    if len(x) < len(y):
        return -1
    elif len(x) > len(y):
        return 1
    else:
        return 0
od = OrderedDict(sorted(d.items(), key=cmp_to_key(comparator)))
for i in od.items():
    print(i)
Хочу сказать, что это же на джаве можно написать раза в 3 короче.

Офлайн

#6 Май 25, 2015 20:00:43

Pawl
Зарегистрирован: 2015-05-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

FishHook
Потратьте час времени на изучение этих четырех типов коллекций и станет гораздо проще.
Что-то мне подсказывает, что если в языке не предусмотрена возможность сортировки карт “искаропки”, то, как ни читай доку, она не появится. В итоге я сделал, что было надо, хоть и с большим количеством кода, но уменьшить его, похоже, не получится Тем не менее, спасибо всем откликнувшимся, кое-что из Ваших ответов я почерпнул!

Отредактировано Pawl (Май 25, 2015 20:01:19)

Офлайн

#7 Май 25, 2015 20:05:07

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

Pawl
Хорошо, а как мне это сделать? Нашел вариант:
Вам просто не нужно этого делать. Не нужен Вам отсортированный словарь. Совсем.
Pawl
но сортирует всё-равно не корректно: только по первым буквам:
Конечно! Вы же не понимаете что пишете.

Офлайн

#8 Май 25, 2015 20:11:28

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

Pawl
Хочу сказать, что это же на джаве можно написать раза в 3 короче.
Это на любом языке будет копрокодом.

Офлайн

#9 Май 25, 2015 20:12:01

Pawl
Зарегистрирован: 2015-05-25
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

Shaman
Конечно! Вы же не понимаете что пишете.
согласен, лямбды я в питоне не понимаю, поэтому и привел свой вариант, который понимаю. В надежде на конструктив.

Офлайн

#10 Май 25, 2015 20:15:51

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

сортировка русских слов компаратором

Рабочий вариант сортировки по всему слову предлагал py.user.next
Чем он вам не нравится?



Отредактировано FishHook (Май 25, 2015 20:16:37)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version