#python-3.x #sorting
#python-3.x #сортировка
Вопрос:
Новичок здесь!
Итак, у меня есть файл .txt, который устроен следующим образом;
(имя) (фамилия) (Возраст) (Город)
(имя) (фамилия) (Возраст) (Город)
(имя) (фамилия) (Возраст) (Город) (имя) (фамилия) (Возраст) (Город) (имя) (фамилия) (Возраст) (Город)
(имя) (фамилия) (Возраст) (Город)
(Имя)(фамилия) (Возраст) (Город)
Что я хочу сделать, так это создать функцию в python, чтобы сохранить ее в том виде, в котором она расположена сейчас, но отсортировать ее в алфавитном порядке по фамилии.
Благодарен за любую помощь!
Ответ №1:
Прочитайте строки, вызовите функцию python .sort
или sorted
, затем напишите строки. Для этого требуется, чтобы весь файл помещался в памяти, что может быть проблемой, если размер файла превышает несколько ГБ.
Функция .sort
принимает необязательный аргумент key
, который можно использовать для указания критерия сортировки; в нашем случае мы можем разбить строку на слова и отсортировать по второму слову.
Обратите внимание, что эта логика работает только в том случае, если мы предполагаем, что имена и фамилии имеют длину ровно в одно слово, что далеко от реальности.
input_filename = 'filename.txt'
output_filename = 'filename.txt'
with open(input_filename, 'r') as f:
l = [line for line in f if line.strip()]
l.sort(key=lambda line:line.split()[1])
with open(output_filename, 'w') as f:
for line in l:
f.write(line)
Примечание: я использовал разные переменные для имен файлов входных и выходных файлов, но это будет работать, даже если вы используете одно и то же имя файла для ввода и вывода.
Условие if line.strip()
при чтении отфильтровывает пустые строки; это позволяет избежать l.sort
жалоб на то, что он не может найти фамилию в пустой строке.
Поскольку мы сортируем по фамилии и ни по чему другому, и поскольку python .sort
стабилен, это сохраняет относительный порядок для людей с одинаковыми фамилиями.
Ответ №2:
Логика для этого проста.
- Считывайте каждую строку в словарь с фамилией в качестве ключа
- Сортировка ключей
- Выводите строки на основе ключа (фамилии)
Попробуйте этот код:
ss = '''
(fname3) (lname8) (12) (NY)
(fname2) (lname7) (34) (PA)
(fname4) (lname9) (11) (SF)
(fname1) (lname4) (40) (LA)
(fname5) (lname5) (5) (LV)
'''.strip()
with open ('names.txt','w') as f: f.write(ss) # write data file
#########################
with open('names.txt') as f:
lines = f.readlines()
d = {ln.split()[1]:ln.strip() for ln in lines} # use last name (col 2) as key
keysort = sorted([k for k in d]) # sort keys
for k in keysort:
print(d[k])
Вывод
(fname1) (lname4) (40) (LA)
(fname5) (lname5) (5) (LV)
(fname2) (lname7) (34) (PA)
(fname3) (lname8) (12) (NY)
(fname4) (lname9) (11) (SF)
Обратите внимание, что вы также можете разбить все строки на массивы, а затем отсортировать строки на основе индекса массива. В этом может помочь модуль csv.