#python #sorting #dictionary
#python #сортировка #словарь
Вопрос:
Мне нужно вывести данные в файл в следующем формате: год-месяц, значение. например, он должен быть отсортирован по году-месяцу:
2016-1,5
2016-7,1
2016-9,3
2016-11,4
2016-12,2
Но я получаю:
2016-1,5
2016-11,4
2016-12,2
2016-7,1
2016-9,3
код выглядит следующим образом:
for k,v in sorted(dictD.items()):
drow = [k,v]
writer.writerow(drow)
Как получить желаемый результат?
Комментарии:
1. Вот почему месяцы и дни обычно записываются с начальными нулями.
2. Даты сортируются лексически. вы можете использовать ключ в функции сортировки, чтобы получить желаемый результат.
3. Тогда
dictD
это не словарь.4. Если вы получаете эту ошибку, как вы получаете неверный вывод, который вы показываете?
5. спасибо @Barmar. Проблема решена. Пожалуйста, объясните ответ.
Ответ №1:
Разделите дату на дефис и преобразуйте ее в кортеж чисел, а не строк.
for row in sorted(dictD.items(), key = lambda(x): map(int, x[0].split('-'))):
writer.writerow(row)
x
это (key, value)
кортеж, возвращаемый items()
, как x[0]
и ключ, который является датой, подобной '2016-1'
. split
разбивает это на кортеж ('2016', '1')
и map(int)
преобразует его в последовательность целых (2016, 1)
чисел . Использование этого в качестве ключа сортировки упорядочит их численно, а не лексикографически.
Ответ №2:
Ну, это не прямой код, но я не смог сделать его более простым, поэтому вы можете попробовать изменить формат месяца следующим образом:
dictD = {'2016-1':5, '2017-7':1,'2016-9':3, '2016-11':4, '2016-12':2}
formatedKey = [list(dictD)[i].split('-')[0] '-' '{:02d}'.format(int(list(dictD)[i].split('-')[1]))
for i in range(len(list(dictD)))]
dictD2 = dict(zip(formatedKey, list(dictD.values())))
for k,v in sorted(dictD2.items()):
drow = [k,v]
print(drow)
Я не пользовался программой writer, но надеюсь, это поможет.
Ответ №3:
Предполагая, что ваш словарь вводится строкой ГГГГ-ММ, а значением является число после запятой, вы можете добавить ключевой аргумент к вашему sorted()
вызову. Ключевая функция может быть:
lambda item: item[0][:5] ('0' if len(item[0]) < 7 else '') item[0][5:]
Итак, ваш отсортированный вызов отправляется из:
sorted(dictD.items())
Для:
sorted(dictD.items(), key=lambda item: <the rest from above>)
Это оставляет сортировку по строкам, но, добавив начальный ноль к однозначному месяцу, все получится так, как вы хотите.
В качестве дополнительного примечания вы можете передать именованную функцию в качестве ключа. Вы не ограничены использованием lambda
вызова.
Когда вы передаете sorted()
данные без указания алгоритма сортировки, используется порядок сортировки по умолчанию. Дикты сортируются по ключам (в виде строк), а кортежи сортируются по элементам кортежа, начиная с первого. Для вас ваш .items()
вызов создает список кортежей (или, по крайней мере, достаточно близких) с ключом в качестве первого элемента кортежа, поэтому кортежи сортируются по ключам dict в виде строк, игнорируя любое потенциальное числовое значение. Добавляя начальный ноль к однозначным месяцам, даты могут быть правильно отсортированы в виде строк. Вызов lambda делает именно это — он добавляет это дополнительное ‘0’, когда это необходимо, чтобы позволить выполнить сортировку с желаемыми результатами.