cmp_to_key не работает в python3 для файлов .csv - PullRequest
1 голос
/ 23 апреля 2020

Я работаю с .csv файлами, поэтому мне нужно отсортировать по заданному столбцу c, этот ответ не работает:

сортировка с двумя ключами = аргументы

, таким образом, используя идею из

Как отсортировать строки Юникода в алфавитном порядке в Python?

у нас есть

в python2

import icu # conda install -c conda-forge pyicu
collator = icu.Collator.createInstance(icu.Locale('el_GR.UTF-8'))
parts = [('3', 'ά', 'C'),
         ('6', 'γ', 'F'),
         ('5', 'β', 'E'),
         ('4', 'Ἀ', 'D'),
         ('2', 'Α', 'B'),
         ('1', 'α', 'A')]
foo = sorted(parts, key=lambda s: (s[1]), cmp=collator.compare)
for c in foo: 
  print c[0], c[1].decode('utf-8'), c[2]

с правильным результатом:

1 α A
2 Α B
4 Ἀ D
3 ά C
5 β E
6 γ F

, но в python3

import icu # conda install -c conda-forge pyicu
from functools import cmp_to_key
collator = icu.Collator.createInstance(icu.Locale('el_GR.UTF-8'))
parts = [('3', 'ά', 'C'),
         ('6', 'γ', 'F'),
         ('5', 'β', 'E'),
         ('4', 'Ἀ', 'D'),
         ('2', 'Α', 'B'),
         ('1', 'α', 'A')]
foo = sorted(parts, key=lambda s: (s[1], collator.getSortKey))
#foo = sorted(parts, key=lambda s: (s[1], collator.compare))#the same result as collator.getSortKey
for c in foo: 
  print (c[0], c[1], c[2])

с неправильным результатом:

2 Α B
1 α A
5 β E
6 γ F
4 Ἀ D
3 ά C

1 Ответ

2 голосов
/ 23 апреля 2020

Я думаю, что ваш вызов отсортирован с неправильной ключевой функцией.

Из документов. python .org :

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

Ваш лямбда-ключ возвращает кортеж, содержащий символ и функцию.

python3 сортирует кортежи сначала первым элементом, поэтому «so» сравнивается с «α» (порядок байтов, а не алфавитный), и если они равны, collator.getSortKey сравнивается с collator.getSortKey.

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

foo = sorted(parts, key=lambda s: collator.getSortKey(s[1]))

Это должно сортировать по алфавиту, а не по порядку байтов.

...