Упростить сортировку имен ячеек Excel в python - PullRequest
0 голосов
/ 22 мая 2018

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

['A1', 'AA1', 'B3', 'B2', 'BB1', 'AZ15']

, где каждое значение похоже на столбец Excel (т. Е. 'BB1' > 'AZ15' > 'AA1' > 'B3' > 'B2' > 'A1').

Вот решение, которое я нашел после прочтенияследующее руководство .

def cmp_cell_ids(name1, name2):
    def split(name):
        letter = ''
        number = ''
        for ch in name:
            if ch in '1234567890':
                number += ch
            else:
                letter += ch
        return letter, int(number)
    ltr1, num1 = split(name1)
    ltr2, num2 = split(name2)
    if len(ltr1) == len(ltr2):
        if ltr1 == ltr2:
            return num1 > num2
        else:
            return ltr1 > ltr2
    return len(ltr1) > len(ltr2)

def cmp_to_key(mycmp):
    class K:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return not mycmp(self.obj, other.obj)
        def __gt__(self, other):
            return mycmp(self.obj, other.obj)
        def __eq__(self, other):
            return self.obj == other.obj
        def __le__(self, other):
            if self.__eq__(other):
                return True
            return self.__lt__(other)
        def __ge__(self, other):
            if self.__eq__(other):
                return True
            return self.__gt__(other)
        def __ne__(self, other):
            return self.obj != other.obj
    return K

key_cell_ids_cmp = cmp_to_key(cmp_cell_ids)
cell_ids = ['A1','AA1','B3','B2','BB1','AZ15']
cell_ids.sort(key=key_cell_ids_cmp)
print(cell_ids)

, которое дает желаемый результат

['A1', 'B2', 'B3', 'AA1', 'AZ15', 'BB1']

Мне интересно, есть ли какая-либо более простая / более питанская реализация для этого (в частности,Я был бы рад, если бы смог избавиться от этого класса-обёртки).

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Очень похоже на решение @ Sneftel's, но я подошел к проблеме, найдя индекс первого числового символа.

import re

A = ['A1', 'AA1', 'B3', 'B2', 'BB1', 'AZ15']

def sorter(x):
    n = re.search('\d', x).start()
    return (len(x[:n]), x[:n], int(x[n:]))

res = sorted(A, key=sorter)

print(res)

['A1', 'B2', 'B3', 'AA1', 'AZ15', 'BB1']
0 голосов
/ 22 мая 2018

Прежде всего, написание (или копирование) функции cmp_to_key не требуется.Просто используйте один из itertools.

В этом случае, однако, было бы намного более естественным использовать ключ!Просто разбейте каждый элемент на кортеж с длиной имени строки (таким образом, B перед AA), строкой строки и целочисленным столбцом, и используйте естественный лексикографический порядок кортежей.

Viz:

import re

def cell_key(cell):
    m = re.match("([A-Z]+)(\\d+)", cell)
    return (len(m.group(1)), m.group(1), int(m.group(2)))

cells = ['A1', 'AA1', 'B3', 'B2', 'BB1', 'AZ15']

print(sorted(cells, key=cell_key))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...