2015-12-22 3 views
0

Предположим, у меня есть txt-файл, каждая строка содержит имя и возраст (имя всегда уникально, но возраст может быть одинаковым).объект сортировки по атрибуту

Может ли кто-нибудь предложить хороший алгоритм для печати имен, пока их возраст находится в порядке возрастания/убывания? (Имена людей, имеющих одинаковый возраст не нужно держать порядок в TXT)

Благодарности

+0

Не могли бы вы привести пример вашего файла и что вы пробовали до сих пор? –

+0

Является ли проблема чтения в файле или сортировки списка кортежей вторым элементом указанных кортежей? – timgeb

+0

Если вы предоставите некоторую попытку, это поможет вашим шансам получить хороший ответ. –

ответ

2

Спасибо, проблема сортировки. Скажем, мы имеем (a, 10), (b, 5), (c, 11). Нужен алгоритм для сортировки его (c, 11), (a, 10), (b, 5)

Хорошо, я предполагаю, что у вас есть эти кортежи в списке. Вы можете использовать встроенную функцию sorted и предоставить ей ключевую функцию, которая задает свойство, по которому сортируются элементы вашего списка.

>>> people = [('bob', 28), ('alice', 21), ('jeff', 78)] 
>>> sorted(people, key=lambda tup: tup[1], reverse=True) 
[('jeff', 78), ('bob', 28), ('alice', 21)] 

Здесь lambda tup: tup[1] вернет второй элемент каждого кортежа. Это значение, по которому сортируются кортежи. reverse=True настроен на сортировку кортежей в порядке убывания.

+2

Используйте operator.itemgetter или operator.attrgetter вместо lambda. (attrgetter, если это namedtuple). Это более идиоматично, а также быстрее. –

+0

@AusanderHuszagh Почему мне нужен импорт для такой тривиальной задачи? – timgeb

+1

Потому что это своего рода точка встроенной библиотеки. Конечно, вы можете написать лямбда, но itemgetter специфичен, это полезно, а также ~ на 50% быстрее. –

1

Если поставить имена/возраст в словаре с чем-то вроде (будет зависеть от фактического формата файла - следующее предполагает название, затем по возрасту в каждой строке, разделенных пробелами):

names = {} 
with open('file.txt') as f: 
    for line in f: 
     name, age = line.split() 
    names[name] = int(age) 

Тогда легко сортировать - сортировать по имени (а не то, что вы предложили, но просто FYI), использование:

sorted(names) 

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

sorted(names, key=lambda i: names[i]) 

Таким образом, для печати, вы можете использовать:

for name in sorted(names, key=lambda i: names[i]): 
    print(name, names[name]) 
4

Альтернатива the answer дается timegeb бы использовать itemgetter из operator пакета (documentation).

from operator import itemgetter 
people = [('bob', 28), ('alice', 21), ('jeff', 78)] 
print(sorted(people, key=itemgetter(1), reverse=True)) 

Который даст вам точно такой же результата

[('jeff', 78), ('bob', 28), ('alice', 21)] 

itemgetter выступает в качестве замены для выражения lambda.

Смежные вопросы