Ответ 1
Или сократите ответ Дэвида с помощью:
if 4 <= day <= 20 or 24 <= day <= 30:
suffix = "th"
else:
suffix = ["st", "nd", "rd"][day % 10 - 1]
Мне интересно, есть ли быстрый и простой способ вывода ординалов с заданным числом в python.
Например, учитывая число 1
, я хотел бы выводить "1st"
, число 2
, "2nd"
и т.д. и т.д.
Это относится к работе с датами в цепочке с палитрой
Home > Venues > Bar Academy > 2009 > April > 01
- это то, что в настоящее время показано
Я хотел бы иметь что-то в строках
Home > Venues > Bar Academy > 2009 > April > 1st
Или сократите ответ Дэвида с помощью:
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
Здесь он использует словари как функцию или как лямбда...
Если вы посмотрите на словари назад, вы можете прочитать их как...
Все заканчивается на 'th'
... если он не заканчивается на 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')))
Более общее и более короткое решение (как функция):
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))
Я только что объединил решения и библиотеки Дэвида (как это делали дедегиды). Вы даже можете заменить переменные (ldig, l2dig) для реальной математики (поскольку l2dig используется только один раз), тогда вы получаете четыре строки кода.
За исключением 1-го, 2-го и 3-го, я думаю, что все они просто добавляют... 4-й, 5-й, 6-й, 11-й, 21-й... ой, oops; -)
Я думаю, это может сработать:
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]
Вот еще более короткое общее решение:
def foo(n):
return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(4 if 10 <= n % 100 < 20 else n % 10, "th")
Хотя другие решения выше, вероятно, легче понять с первого взгляда, это работает так же хорошо, используя немного меньше кода.
Исправлено для отрицательных входов на основе eric.frederich nice sol'n (добавлено 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')))
Мне пришлось преобразовать script из javascript, где у меня был полезный fn, который реплицировал php 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 - я попал сюда из другого потока, который был указан как дубликат, но это было не совсем так, поскольку этот поток также затронул проблему даты
Я хотел использовать ординалы для моего проекта, и после нескольких прототипов я думаю, что этот метод, хотя и не малый, будет работать для любого положительного целого числа, да любое целое число.
Он работает, определяя, если число выше или ниже 20, если число ниже 20, оно превратит int 1 в строку 1, 2, 2; 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" для удобства использования и может быть вызван путем импорта имени файла, которое я назвал "порядковым", по порядку импорта, а затем по порядку. (номер).
Дайте мне знать, что вы думаете: D
P.S. Я отправил этот ответ на другой вопрос ординалов, но понял, что это более применимо, учитывая его 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)
В эти дни я бы использовал 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)