Есть ли способ сортировки вложенных списков без использования operator.itemgetter?

1

У меня есть файл, который я читаю, а затем создаю вложенные списки, которые я хочу отсортировать по 4 элемента (zipcode)

jk43:23 Marfield Lane:Plainview:NY:10023
axe99:315 W. 115th Street, Apt. 11B:New York:NY:10027
jab44:23 Rivington Street, Apt. 3R:New York:NY:10002
ap172:19 Boxer Rd.:New York:NY:10005
jb23:115 Karas Dr.:Jersey City:NJ:07127
jb29:119 Xylon Dr.:Jersey City:NJ:07127
ak9:234 Main Street:Philadelphia:PA:08990

Вот мой код:

ex3_3 = open('ex1.txt')
exw = open('ex2_sorted.txt', 'w')

data = []
for line in ex3_3:
    items = line.rstrip().split(':')
    data.append(items)
print sorted(data, key=operator.itemgetter(4))

Вывод:

[['jb23', '115 Karas Dr.', 'Jersey City', 'NJ', '07127'], ['jb29', '119 Xylon Dr.', 'Jersey City', 'NJ', '07127'], ['ak9', '234 Main Street', 'Philadelphia', 'PA', '08990'], ['jab44', '23 Rivington Street, Apt. 3R', 'New York', 'NY', '10002'], ['ap172', '19 Boxer Rd.', 'New York', 'NY', '10005'], ['jk43', '23 Marfield Lane', 'Plainview', 'NY', '10023'], ['axe99', '315 W. 115th Street, Apt. 11B', 'New York', 'NY', '10027']]

все это прекрасно работает, мне просто интересно, есть ли способ сделать это без использования "оператора импорта"?

  • 3
    Почему бы не захотеть использовать какой-либо import ?
  • 0
    @naeg: Я думаю, что OP означает: без импорта модуля operator .
Показать ещё 2 комментария
Теги:
sorting
nested-lists

3 ответа

6
Лучший ответ

О да, есть способ:

print sorted(data,key=lambda x: x[4])
3

Грубым workalike будет:

print sorted(data, key=lambda items: items[4])

но operator.itemgetter немного быстрее. Я использую эту программу для сравнения обоих подходов:

#!/usr/bin/env python

import timeit

withlambda = 'lst.sort(key=lambda items: items[4])'
withgetter = 'lst.sort(key=operator.itemgetter(4))'

setup = """\
import random
import operator
random.seed(0)
lst = [(random.randrange(100000), random.randrange(100000), random.randrange(100000), random.randrange(100000) ,random.randrange(100000))
       for _ in range(10000)]
"""

n = 10000

print "With lambda:"
print timeit.timeit(withlambda, setup, number=n)

print "With getter:"
print timeit.timeit(withgetter, setup, number=n)

Он создает случайный список из 100 000 5-позиционных кортежей, а затем выполняет sort() в списке 1000 раз. На моем MacBook Pro с Python 2.7.2, то withlambda версия работает примерно 55.4s и withgetter работает в около 46.1s.

Обратите внимание, что по мере увеличения списков время, затрачиваемое на алгоритм сортировки, растет быстрее, чем время, затрачиваемое на извлечение ключей. Поэтому разница намного больше, если вы сортируете множество небольших списков. Запуск же тест со списком в 1000 пункта повторяется 100000 раз Урожайность 22.4s для withlambda против 12.5s для withgetter.

  • 0
    На самом деле, не намного быстрее в случайных списках из 100 000 элементов: примерно на 8% быстрее.
  • 0
    Я получил примерно 18% быстрее в списках из 100 000 элементов против 41% быстрее в списках из 10000 элементов. Я думаю, это имеет смысл, так как издержки самой сортировки растут быстрее, чем длина списка. Замена sorted() на map() дала ускорение 55%. Мораль: оба быстры. Itemgetter быстрее. Выберите тот, который наиболее читабелен для вас, если вы не хотите иметь самый быстрый.
Показать ещё 5 комментариев
0

Постройте или реорганизуйте свой подсписчик, чтобы первое, что вы хотите сортировать. В вашем случае почтовый индекс, а не элемент 4, должен быть элементом 0. Затем вы можете просто отсортировать их.

Разумеется, необходимо также учитывать пригодность этого заказа для других видов использования данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню