2015-02-10 2 views
2

Мне известно, что сортировка списка списка содержит слова по длине. Что означает список:Сортировка группы слов внутри списка

[[],['hello','indent'],['hi','monday'],['hi','low']] 

результате которого при сортировке ключ, длина и наоборот:

[['hello','indent','joe'],['hi','monday'],['hi','low'],[]] 

Но что я хочу, это своего рода как по длине, и те, имеющие одинаковую длину, должны быть отсортированы в алфавитном порядке. то есть «низкий» < «понедельник» так, что вывод должен быть:

[['hello','indent','joe'],['hi','low'],['hi','monday'],[]] 

Какой тип ключа я должен использовать для сортировки, используя встроенный вид?

EDIT: но что делать, если входы смешанного корпуса? Что делать, если это:

[['Hi', 'monday'], [], ['hello', 'indent', 'joe'], ['hi', 'low']]

и желаемый результат будет:

[['hello', 'indent', 'joe'], ['hi', 'monday'],['Hi', 'low'], []] 
+1

Вы должны использовать один и тот же '.sort()' он будет неявно генерировать ожидаемый результат, я думаю – ZdaR

+1

Можете ли вы попробовать создать пользовательскую функцию и передать ее в 'key'. –

ответ

1

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

a = [['hi', 'monday'], [], ['hello', 'indent', 'joe'], ['hi', 'low']] 
a.sort(key=lambda l:(-len(l), l)) 
print a 

выход

[['hello', 'indent', 'joe'], ['hi', 'low'], ['hi', 'monday'], []] 

Чтобы получить строчные буквы предшествуют заглавные буквы мы можем просто использовать str.swapcase() метод на строках в каждом подспискоме:

a = [['Hi', 'monday'], [], ['hello', 'indent', 'joe'], ['hi', 'low']] 
a.sort(key=lambda l:(-len(l), [s.swapcase() for s in l])) 
print a 

[['hello', 'indent', 'joe'], ['hi', 'low'], ['Hi', 'monday'], []] 

И если вы хотите сортировку быть чувствителен к регистру:

a = [['Hi', 'monday'], [], ['hello', 'indent', 'joe'], ['hi', 'low']] 
a.sort(key=lambda l:(-len(l), [s.lower() for s in l])) 
print a 

выхода

[['hello', 'indent', 'joe'], ['hi', 'low'], ['Hi', 'monday'], []] 
+0

Это кажется идеальным в случае буквы в нижнем регистре, но что, если входы смешанного случая?Что делать, если это [[«Привет», «Понедельник»], [], ['hello', 'indent', 'joe'], ['hi', 'low']], а желаемый результат будет: [['hello', 'indent', 'joe'], ['hi', 'monday'], ['Hi', 'low'], []] –

+0

@galipremsagar: Это немного сложнее потому что заглавные буквы предшествуют строчным буквам в порядке сортировки по умолчанию ASCII. Например, 'ord ('H') == 72' и' ord ('h') == 104'. Но, к счастью, мы можем обойти это с помощью простого трюка. –

+0

Что это за трюк или ключ, который сортирует как по длине списка, так и по алфавитной сортировке на основе нечувствительного к регистру порядка? –

1

Сначала сортировать по алфавиту, то сортировка по длине в обратном порядке.

>>> lst = [['hi', 'monday'], [], ['hello', 'indent', 'joe'], ['hi', 'low']] 
>>> lst.sort() 
>>> lst.sort(key=len, reverse=True) 
>>> print lst 
>>> [['hello', 'indent', 'joe'], ['hi', 'low'], ['hi', 'monday'], []] 

Порядок элементов в результирующий набор сильно зависит от текущей локали . Если вы хотите, чтобы ваш алгоритм сортировки учитывал локаль при сортировке элементов, вы можете сделать следующее:

>>> import locale 
>>> from functools import cmp_to_key 
>>> 
>>> # You can change your locale like below; 
>>> # locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') 
>>> 
>>> lst = [['hi', 'monday'], [], ['hello', 'indent', 'joe'], ['hi', 'low']] 
>>> print sorted([sorted(item, key=cmp_to_key(locale.strcoll)) for item in lst], key=len, reverse=True) 
>>> [['hello', 'indent', 'joe'], ['hi', 'monday'], ['hi', 'low'], []] 
Смежные вопросы