Как может я эффективно и легко сортировать список кортежей, не будучи чувствительным к регистру?
Например, это:
[('a', 'c'), ('A', 'b'), ('a', 'a'), ('a', 5)]
Должен быть похожим это когда-то отсортировало:
[('a', 5), ('a', 'a'), ('A', 'b'), ('a', 'c')]
Регулярный лексикографический вид поместит перед и приведет к этому:
[('A', 'b'), ('a', 5), ('a', 'a'), ('a', 'c')]
Вы можете использовать аргумент key
sort
, чтобы определить, как вы хотите рассматривать каждый элемент в отношении сортировки:
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 для объяснения того, как использовать ключ
.
Должно получиться что-то вроде этого:
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
, если ваш список длинный.
list_of_tuples.sort(key=lambda t : tuple(s.lower() if isinstance(s,basestring) else s for s in t))
Вот решение, в котором используется идея декоратора, проиллюстрированная в разделе «Сортировка по ключам» вики-статьи 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]
Упрощенная версия Пола Макгуайра работает:
list_of_tuples.sort(key=lambda t : tuple(t[0].lower()))
(где t [0] указывает, какой элемент кортежа вы хотите использовать, в данном случае первый)