как напечатать год-месяц в правильном порядке

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