Сортировать список кортежей без учета регистра - PullRequest
5 голосов
/ 22 марта 2010

Как я могу эффективно и легко отсортировать список кортежей без учета регистра?

Например, это:

[('a', 'c'), ('A', 'b'), ('a', 'a'), ('a', 5)]

Должно выглядеть как-то отсортировано:

[('a', 5), ('a', 'a'), ('A', 'b'), ('a', 'c')]

Обычная лексикографическая сортировка ставит 'A' перед 'a' и выдает это:

[('A', 'b'), ('a', 5), ('a', 'a'), ('a', 'c')]

Ответы [ 5 ]

10 голосов
/ 22 марта 2010

Вы можете использовать sort 'key аргумент, чтобы определить, как вы хотите рассматривать каждый элемент в отношении сортировки:

def lower_if_possible(x):
    try:
        return x.lower()
    except AttributeError:
        return x

L=[('a', 'c'), ('A', 'b'), ('a', 'a'), ('a', 5)]

L.sort(key=lambda x: map(lower_if_possible,x))
print(L)

См. http://wiki.python.org/moin/HowTo/Sorting для объяснения того, как использовать key.

2 голосов
/ 22 марта 2010
list_of_tuples.sort(key=lambda t : tuple(s.lower() if isinstance(s,basestring) else s for s in t))
0 голосов
/ 25 июня 2010

Упрощенная версия работ Пола МакГуайра:

list_of_tuples.sort(key=lambda t : tuple(t[0].lower()))

(где t [0] указывает, какой элемент кортежа вы хотите использовать, в данном случае первый)

0 голосов
/ 22 марта 2010

Вот решение, которое использует идею декоратора, проиллюстрированную в разделе «Сортировка по ключам» статьи вики Python (http://wiki.python.org/moin/HowTo/Sorting/).

# Create a list of new tuples whose first element is lowercase
# version of the original tuple.  I use an extra function to
# handle tuples which contain non-strings.
f = lambda x : x.lower() if type(x)==str else x
deco = [(tuple(f(e) for e in t), t) for t in ex]

# now we can directly sort deco and get the result we want
deco.sort()

# extract the original tuples in the case-insensitive sorted order
out = [t for _,t in deco]
0 голосов
/ 22 марта 2010

Примерно так должно работать:

def sort_ci(items):
    def sort_tuple(tuple):
        return ([lower(x) for x in tuple],) + tuple
    temp = [sort_tuple(tuple) for tuple in items]
    temp.sort()
    return [tuple[1:] for tuple in temp]

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

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

...