Как работают operator.itemgetter и sort() в Python?
У меня есть следующий код:
# initialize
a = []
# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John", 8, "Student"])
a.append(["Paul", 22, "Car Dealer"])
a.append(["Mark", 66, "Retired"])
# sort the table by age
import operator
a.sort(key=operator.itemgetter(1))
# print the table
print(a)
Он создает таблицу 4x3, а затем сортирует ее по возрасту. Мой вопрос в том, что именно делает key=operator.itemgetter(1)
? Возвращает ли функция operator.itemgetter
значение элемента? Почему я не могу просто ввести что-то вроде key=a[x][1]
? Или я могу? Как с помощью оператора можно напечатать определенное значение вида 3x2
которое равно 22
?
-
Как точно Python сортирует таблицу? Могу ли я его отсортировать?
-
Как я могу сортировать его на основе двух столбцов, таких как первый возраст, а затем, если возраст совпадает с именем b?
-
Как я мог сделать это без operator
?
Ответы
Ответ 1
Похоже, ты немного запутался во всем этом.
operator
- это встроенный модуль, предоставляющий набор удобных операторов. В двух слова operator.itemgetter(n)
создает вызываемый, который принимает итерируемый объект (например, list, tuple, set) в качестве входных данных и извлекает из него n-й элемент.
Таким образом, вы не можете использовать key=a[x][1]
там, потому что python не знает, что такое x
. Вместо этого вы можете использовать lambda
функцию (elem
- это просто имя переменной, без магии):
a.sort(key=lambda elem: elem[1])
Или просто обычная функция:
def get_second_elem(iterable):
return iterable[1]
a.sort(key=get_second_elem)
Итак, здесь важно отметить: в функциях python есть первоклассные граждане, поэтому вы можете передать их другим функциям в качестве параметра.
Другие вопросы:
- Да, вы можете отменить сортировку, просто добавьте
reverse=True
: a.sort(key=..., reverse=True)
- Чтобы отсортировать несколько столбцов, вы можете использовать
itemgetter
с несколькими индексами: operator.itemgetter(1,2)
или с lambda: lambda elem: (elem[1], elem[2])
. Таким образом, итераторы построены "на лету" для каждого элемента в списке, которые сравниваются друг с другом в лексикографическом (?) Порядке (сравниваются первые элементы, если они равны - второй элемент сравнивается и т.д.), - Вы можете получить значение в [3,2], используя
a[2,1]
(индексы основаны на нуле). Использование оператора... Это возможно, но не так просто, как просто индексирование.
Подробнее см. В документации:
-
operator.itemgetter
объяснен - Сортировка списка по пользовательскому ключу в Python
Ответ 2
Ответ для начинающих Python
Проще говоря:
- Для параметра
key=
sort
требуется ключевая функция (которая будет применяться для сортировки объектов), а не одно ключевое значение и - это то, что
operator.itemgetter(1)
даст вам: функция, которая захватывает первый элемент из списка-подобного объекта.
(Точнее это callables, а не функции, но это разница, которую часто можно игнорировать).
Ответ 3
Вы задаете много вопросов, на которые вы можете ответить сами, прочитав документацию, поэтому я дам вам общий совет: прочитайте его и поэкспериментируйте в оболочке python. Вы увидите, что itemgetter
возвращает вызываемый:
>>> func = operator.itemgetter(1)
>>> func(a)
['Paul', 22, 'Car Dealer']
>>> func(a[0])
8
Чтобы сделать это по-другому, вы можете использовать lambda
:
a.sort(key=lambda x: x[1])
И наоборот:
a.sort(key=operator.itemgetter(1), reverse=True)
Сортировка по нескольким столбцам:
a.sort(key=operator.itemgetter(1,2))
См. Раздел " Сортировка".
Ответ 4
#sorting first by age then profession,you can change it in function "fun".
a = []
def fun(v):
return (v[1],v[2])
# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John", 8, "Student"])
a.append(["Paul", 8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])
a.sort(key=fun)
print a
Ответ 5
a = []
a.append(["Nick", 30, "Doctor"])
a.append(["John", 8, "Student"])
a.append(["Paul", 8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])
print a
[['Nick', 30, 'Doctor'], ['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Mark', 66, 'Retired']]
def _cmp(a,b):
if a[1]<b[1]:
return -1
elif a[1]>b[1]:
return 1
else:
return 0
sorted(a,cmp=_cmp)
[['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Nick', 30, 'Doctor'], ['Mark', 66, 'Retired']]
def _key(list_ele):
return list_ele[1]
sorted(a,key=_key)
[['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Nick', 30, 'Doctor'], ['Mark', 66, 'Retired']]
>>>