Как заставить метод формата питонов размещать значения по мере их оценки - PullRequest
0 голосов
/ 05 июля 2019

Мне нужно вычислить отчетный год на основе даты, пока я использую метод форматирования с объектом datetime.datetime, он генерирует неожиданные результаты для объектов одного типа с разными значениями

Ниже мой код.

from datetime import datetime

dt = datetime.strptime('2019-03-03','%Y-%m-%d')
## Below line is killing my mind as it is resulting 2019-2018
print('{}-{}'.format(dt.year, (dt.year+1)%100 if dt.month > 3 else dt.year-1,(dt.year)%100))
# This will produce the result 3 2019 19
print(dt.month, dt.year, (dt.year)%100)

dt = datetime.strptime('2019-04-04','%Y-%m-%d')
# But the below line is working fine as it is resulting 2019-20
print('{}-{}'.format(dt.year, (dt.year+1)%100 if dt.month > 3 else dt.year-1,(dt.year)%100))
# This will produce the result 4 2019 19
print(dt.month, dt.year, (dt.year)%100)

Я ожидаю результата

2018-19 if dt = datetime.strptime('2019-03-03','%Y-%m-%d')
2019-20 if dt = datetime.strptime('2019-04-04','%Y-%m-%d')

Я не могу выяснить проблему с кодом.

1 Ответ

1 голос
/ 05 июля 2019
## Below line is killing my mind as it is resulting 2019-2018
print('{}-{}'.format(dt.year, (dt.year+1)%100 if dt.month > 3 else dt.year-1,(dt.year)%100))

Хорошо, давайте разберем ваш код:

'{}-{}'.format(dt.year, (dt.year+1)%100 if dt.month > 3 else dt.year-1,(dt.year)%100)

У вас есть 2 {} s, но 3 (!) Аргумента:

  • dt.year,
  • (dt.year+1)%100 if dt.month > 3 else dt.year-1,
  • (dt.year)%100 (игнорируется, поскольку есть только 2 {} с)

Как вы можетесмотрите, if/else работает только для среднего аргумента.

Вам нужно использовать это if для обоих аргументов, поэтому вам нужно либо повторить оператор if, либо использовать скобки для группировки вещей.Но группировка приведет к кортежу, поэтому вам нужно распаковать значения с помощью * (я упомянул группировку в комментариях, но забыл об распаковке).

Решение с 2 ifs:

'{}-{}'.format(dt.year if dt.month > 3 else dt.year-1, 
               (dt.year+1)%100 if dt.month > 3 else (dt.year)%100)

Как видите, одна запятая - два аргумента.Для удобства чтения разбили его на две строки.

Решение с одной распаковкой if и tuple:

'{}-{}'.format( *(dt.year, (dt.year+1)%100) if dt.month > 3 else *(dt.year-1,(dt.year)%100) )

Почему распаковка?Потому что '{}-{}'.format( ('2018','19') ) получает один аргумент, который является кортежем, а не два аргумента.Он не знает, что с этим делать.* впереди распаковывает списки или кортежи и предоставляет их как обычные аргументы.- Подробнее об этом здесь, в документации .

...