Сортировать список строк, игнорируя верхний / нижний регистр

У меня есть список, который содержит строки, представляющие имена животных. Мне нужно отсортировать список. Если я использую sorted(list), он выдаст список вывода сначала с заглавными строками, а затем строчными.

Но мне нужен следующий вывод.

Входные данные:

var = ['ant','bat','cat','Bat','Lion','Goat','Cat','Ant']

Выход:

['ant', 'Ant', 'bat', 'Bat', 'cat', 'Cat', 'Goat', 'Lion']

3 ответа

Решение

sort() метод и sorted() Функция принимает ключевой аргумент:

var.sort(key=lambda v: v.upper())

Функция, названная в key вызывается для каждого значения, а возвращаемое значение используется при сортировке, не влияя на действительные значения:

>>> var=['ant','bat','cat','Bat','Lion','Goat','Cat','Ant']
>>> sorted(var, key=lambda v: v.upper())
['ant', 'Ant', 'bat', 'Bat', 'cat', 'Cat', 'Goat', 'Lion']

Сортировать Ant до antвам нужно будет включить в ключ немного больше информации, чтобы в противном случае равные значения были отсортированы в указанном порядке:

>>> sorted(var, key=lambda v: (v.upper(), v[0].islower()))
['Ant', 'ant', 'Bat', 'bat', 'Cat', 'cat', 'Goat', 'Lion']

Более сложный ключ генерирует ('ANT', False) за Ant, а также ('ANT', True) за ant; True сортируется после False и поэтому слова в верхнем регистре сортируются до их эквивалента в нижнем регистре.

Смотрите раздел Python HOWTO для получения дополнительной информации.

Новый ответ для Python 3, я хотел бы добавить два пункта:

  1. использование str.casefold для сравнения без учета регистра.
  2. Используйте метод напрямую, а не внутри лямбды.

То есть:

var = ['ant','bat','cat','Bat','Lion','Goat','Cat','Ant']

var.sort(key=str.casefold)

(который сортирует на месте) и сейчас:

>>> var
['ant', 'Ant', 'bat', 'Bat', 'cat', 'Cat', 'Goat', 'Lion']

Или, чтобы вернуть новый список, используйте sorted

>>> var = ['ant','bat','cat','Bat','Lion','Goat','Cat','Ant']
>>> sorted(var, key=str.casefold)
['ant', 'Ant', 'bat', 'Bat', 'cat', 'Cat', 'Goat', 'Lion']

Почему это отличается от str.lower или же str.upper? Согласно документации:

Свертывание регистров похоже на нижний регистр, но более агрессивно, потому что оно предназначено для удаления всех различий регистра в строке. Например, немецкая строчная буква 'ß' эквивалентно "ss", Так как это уже в нижнем регистре, str.lower() не будет делать ничего, чтобы 'ß'; casefold() преобразует его в "ss",

Мне нужно добавить еще один ответ, поскольку как в принятом ответе, так и в более новых версиях отсутствует одна важная вещь:

Предлагаемая здесь сортировка без учета регистра нестабильна при упорядочении "равных" ключей!

Это означает: когда у вас есть смесь строк со смешанным регистром, которые вы хотите отсортировать, вы получаете правильно отсортированный список, но не определено, стоит ли "AbC" до "aBc" или после. Это может даже различаться между запусками одной и той же программы.

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

sorted(var, key=lambda v: (v.casefold(), v))

Таким образом, исходный ключ всегда добавляется как резервный порядок, когда версия casefold не предоставляет различий для сортировки.

Мы можем использовать функцию 'sorted' в соответствии с документацией Python Sorting HOW TO.

a = sorted(Input, key=str.lower)print("Output1: ",a)

Output1:

['ant', 'Ant', 'bat', 'Bat', 'cat', 'Cat', 'Goat', 'Lion']
Другие вопросы по тегам