Дата Порядковый Выход?
Мне интересно, есть ли быстрый и простой способ вывода ординалов с заданным числом в Python.
Например, учитывая номер 1
Я хотел бы вывести "1st"
, число 2
, "2nd"
и так далее, и так далее.
Это для работы с датами в хлебной крошке
Home > Venues > Bar Academy > 2009 > April > 01
это то, что в настоящее время показано
Я хотел бы иметь что-то вроде
Home > Venues > Bar Academy > 2009 > April > 1st
15 ответов
Или сократить ответ Дэвида с:
if 4 <= day <= 20 or 24 <= day <= 30:
suffix = "th"
else:
suffix = ["st", "nd", "rd"][day % 10 - 1]
Вот более общее решение:
def ordinal(n):
if 10 <= n % 100 < 20:
return str(n) + 'th'
else:
return str(n) + {1 : 'st', 2 : 'nd', 3 : 'rd'}.get(n % 10, "th")
Не уверен, существовал ли он 5 лет назад, когда вы задавали этот вопрос, но в пакете inflect есть функция, которая делает то, что вы ищете:
>>> import inflect
>>> p = inflect.engine()
>>> for i in range(1,32):
... print p.ordinal(i)
...
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
10th
11th
12th
13th
14th
15th
16th
17th
18th
19th
20th
21st
22nd
23rd
24th
25th
26th
27th
28th
29th
30th
31st
В эти дни я использовал Arrow http://arrow.readthedocs.io/en/latest/ (которого точно не было в '09)
>>> import arrow
>>> from datetime import datetime
>>> arrow.get(datetime.utcnow()).format('Do')
'27th'
Я сделал функцию, которая, кажется, работает в этом случае. Просто передайте объект даты, и он будет использовать день для определения суффикса. Надеюсь, поможет
from datetime import date
def get_day_ordinal(d):
sDay = '%dth'
if d.day <= 10 or d.day >= 21:
sDay = '%dst' if d.day % 10 == 1 else sDay
sDay = '%dnd' if d.day % 10 == 2 else sDay
sDay = '%drd' if d.day % 10 == 3 else sDay
return sDay % d.day
d = date.today()
print get_day_ordinal(d)
Более общее и короткое решение (как функция):
def get_ordinal(num)
ldig = num % 10
l2dig = (num // 10) % 10
if (l2dig == 1) or (ldig > 3):
return '%d%s' % (num, 'th')
else:
return '%d%s' % (num, {1: 'st', 2: 'nd', 3: 'rd'}.get(ldig))
Я просто объединил решения и библиотеки Дэвида (как и в deegeedubs). Вы даже можете заменить переменные (ldig, l2dig) для реальной математики (поскольку l2dig используется только один раз), тогда вы получите четыре строки кода.
Здесь он использует словари как функцию или как лямбду...
Если вы посмотрите на словари в обратном направлении, вы можете прочитать их как...
Все заканчивается в "й"
... если оно не заканчивается на 1, 2 или 3, то заканчивается на 'st', 'nd' или 'rd'
... если это не заканчивается в 11, 12 или 13, то это заканчивается в "th," th "или" th "
# as a function
def ordinal(num):
return '%d%s' % (num, { 11: 'th', 12: 'th', 13: 'th' }.get(num % 100, { 1: 'st',2: 'nd',3: 'rd',}.get(num % 10, 'th')))
# as a lambda
ordinal = lambda num : '%d%s' % (num, { 11: 'th', 12: 'th', 13: 'th' }.get(num % 100, { 1: 'st',2: 'nd',3: 'rd',}.get(num % 10, 'th')))
Исправлено для отрицательных входных данных, основанных на хорошем решении eric.frederich (только что добавлено abs
когда используешь %
):
def ordinal(num):
return '%d%s' % (num, { 11: 'th', 12: 'th', 13: 'th'}.get(abs(num) % 100, { 1: 'st',2: 'nd',3: 'rd',}.get(abs(num) % 10, 'th')))
За исключением 1-го, 2-го и 3-го, я думаю, что они все просто добавляют th... 4-е, 5-е, 6-е, 11-е, 21-е... о, упс;-)
Я думаю, что это может сработать:
def ordinal(num):
ldig = num % 10
l2dig = (num // 10) % 10
if l2dig == 1:
suffix = 'th'
elif ldig == 1:
suffix = 'st'
elif ldig == 2:
suffix = 'nd'
elif ldig == 3:
suffix = 'rd'
else:
suffix = 'th'
return '%d%s' % (num, suffix)
def ordinal(n):
return ["th", "st", "nd", "rd"][n%10 if n%10<4 and not (10<n%100<14) else 0]
Я хотел использовать ординалы для моего проекта, и после нескольких прототипов я думаю, что этот метод, хотя и не маленький, будет работать для любого положительного целого числа, да любого целого числа.
Он работает путем определения, если число больше или меньше 20, если число меньше 20, он превратит int 1 в строку 1st, 2, 2nd; 3, 3; а остальные добавят к нему "st".
Для чисел свыше 20 потребуется последняя и вторая до последней цифры, которые я назвал десятками и единицами соответственно, и проверим их, чтобы увидеть, что добавить к числу.
Между прочим, это в python, поэтому я не уверен, смогут ли другие языки найти последнюю или последнюю или последнюю цифру в строке, если они это сделают, это должно довольно легко перевести.
def o(numb):
if numb < 20: #determining suffix for < 20
if numb == 1:
suffix = 'st'
elif numb == 2:
suffix = 'nd'
elif numb == 3:
suffix = 'rd'
else:
suffix = 'th'
else: #determining suffix for > 20
tens = str(numb)
tens = tens[-2]
unit = str(numb)
unit = unit[-1]
if tens == "1":
suffix = "th"
else:
if unit == "1":
suffix = 'st'
elif unit == "2":
suffix = 'nd'
elif unit == "3":
suffix = 'rd'
else:
suffix = 'th'
return str(numb)+ suffix
Я назвал функцию "o" для простоты использования и может быть вызван путем импорта имени файла, которое я назвал "ординал", путем импорта ordinal, а затем ordinal.o(число).
Дайте мне знать, что вы думаете: D
PS Я разместил этот ответ на другом вопросе по порядковым номерам, но понял, что этот вопрос более применим, учитывая, что это python.
Вот функция, которую я написал как часть программы типа календаря, которую я написал (я не включаю всю программу). Это добавляет правильный порядковый номер для любого числа больше 0. Я включил цикл для демонстрации вывода.
def ordinals(num):
# st, nums ending in '1' except '11'
if num[-1] == '1' and num[-2:] != '11':
return num + 'st'
# nd, nums ending in '2' except '12'
elif num[-1] == '2' and num[-2:] != '12':
return num + 'nd'
# rd, nums ending in '3' except '13'
elif num[-1] == '3' and num[-2:] != '13':
return num + 'rd'
# th, all other nums
else:
return num + 'th'
data = ''
# print the first 366 ordinals (for leap year)
for i in range(1, 367):
data += ordinals(str(i)) + '\n'
# print results to file
with open('ordinals.txt', 'w') as wf:
wf.write(data)
Прозрачное решение без всякой гимнастики:
_DATE_DAY_SUFFIXES = {
1: 'st',
2: 'nd',
3: 'rd',
}
def day_suffix(d):
if 10 <= d <= 19:
return 'th'
d = d % 10
try:
return _DATE_DAY_SUFFIXES[d]
except KeyError:
return 'th'
Вот еще более короткое общее решение:
def foo(n):
return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(4 if 10 <= n % 100 < 20 else n % 10, "th")
Хотя другие решения, описанные выше, вероятно, легче понять с первого взгляда, это работает так же хорошо, при использовании немного меньшего количества кода.
Мне пришлось конвертировать скрипт из JavaScript, где у меня был полезный fn, который реплицировал phps date obj. Очень похожий
def ord(n):
return str(n)+("th" if 4<=n%100<=20 else {1:"st",2:"nd",3:"rd"}.get(n%10, "th"))
это связано с моим стайлером даты:
def dtStylish(dt,f):
return dt.strftime(f).replace("{th}", ord(dt.day))
PS-Я получил здесь из другого потока, который был отмечен как дубликат, но это не было полностью, так как этот поток также обратился к проблеме даты