Как работают 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?

  1. Как точно Python сортирует таблицу? Могу ли я его отсортировать?

  2. Как я могу сортировать его на основе двух столбцов, таких как первый возраст, а затем, если возраст совпадает с именем b?

  3. Как я мог сделать это без 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 есть первоклассные граждане, поэтому вы можете передать их другим функциям в качестве параметра.

Другие вопросы:

  1. Да, вы можете отменить сортировку, просто добавьте reverse=True: a.sort(key=..., reverse=True)
  2. Чтобы отсортировать несколько столбцов, вы можете использовать itemgetter с несколькими индексами: operator.itemgetter(1,2) или с lambda: lambda elem: (elem[1], elem[2]). Таким образом, итераторы построены "на лету" для каждого элемента в списке, которые сравниваются друг с другом в лексикографическом (?) Порядке (сравниваются первые элементы, если они равны - второй элемент сравнивается и т.д.),
  3. Вы можете получить значение в [3,2], используя a[2,1] (индексы основаны на нуле). Использование оператора... Это возможно, но не так просто, как просто индексирование.

Подробнее см. В документации:

  1. operator.itemgetter объяснен
  2. Сортировка списка по пользовательскому ключу в Python

Ответ 2

Ответ для начинающих Python

Проще говоря:

  1. Для параметра key= sort требуется ключевая функция (которая будет применяться для сортировки объектов), а не одно ключевое значение и
  2. это то, что 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']]
>>>