动态查找带循环的序数:find th - st - nd - rd
Find ordinal numbers with loop dynamically: find th - st - nd - rd
我想动态地找到正确的序数根,例如:
111 = 111st
112 = 112nd
113 = 113rd ...
我尝试了其他解决方案,但找不到合适的解决方案。
这是我的代码:
for number in range(1, 114):
print(number)
ex1 = 11
ex2 = 12
ex3 = 13
if number == ex1:
print("is the " + str(number) + "th number.")
elif number % 10 == 1 or not ex1:
print("is the " + str(number) + "st number.")
elif number == ex2:
print("is the " + str(number) + "nd number.")
elif number % 10 == 2 or not ex2:
print("is the " + str(number) + "nd number.")
elif number == ex3:
print("is the " + str(number) + "rd number.")
elif number % 10 == 3 or not ex3:
print("is the " + str(number) + "rd number")
else:
print("is the " + str(number) + "th number.")
这是一个很好的解决方案:
ordinal = lambda n: "%d%s" % (n, "tsnrhtdd"[(n // 10 % 10 != 1) * (n % 10 < 4) * n % 10::4])
for number in range(1, 114):
print(f'the {ordinal(number)} number. :) ')
为人类编辑
注意:变量名称不适合在生产环境中使用,我试图更明确地说明 lambda 函数的每个步骤的作用!
def get_ordinal(n):
hacking_string = "tsnrhtdd" # 1)
is_num_divisible_by_ten = (n // 10 % 10 != 1) # 2)
is_num_reminder_0_3= (n % 10 < 4) # 3)
are_both_false_or_both_true= is_num_divisible_by_ten * is_num_between_0_3 # 4)
get_index = are_both_false_or_both_true* n % 10 # 5)
return f'{number}{hacking_string[get_index::4]}' #6) ---> starts at t | s | n | r
for number in range(1, 114):
print(f'the {get_ordinal(number)} number. :) ')
注意事项
找到的解决方案非常 Hacky 和聪明,我可能永远不会自己想出,正在使用一些聪明的数学技巧来找到数字的偏移集。
然而,根据要求,我简化了函数并添加了一些解释。
步骤 1. 这个字符串最好看成这个 "tsnr" "htdd" |左边是弦的“根”,右边是末尾。 (下面有更多解释)
第 2 步。is_num_divisible_by_ten
--> 使用 floor division 结果为 True 或 False。
第3步。is_num_reminder_0_3
如果检查N和10的提醒是否在0和3之间,returns一个真/假标志。
步骤 4. are_both_false_or_both_true
乘以 2 bool 值,在 Python True 是 1,False 是 0,所以就像做 --> 1 * 0 . 只有当两个值都为真或都为假时,变量才为真,否则始终为假。
第 5 步。get_index
- > Returns 0 or 1 or 2 or 3.
第 6 步。这里是 hacky 部分,使用从 get_index 接收到的索引,是使用 hacking_string
变量和 indexing-and-slicing:
get_index 值始终是以下之一:“tsnr”和采取的步骤 (4) 这些“rhtdd”中的任何一个,因此可能的组合是:
get_index = 0 = "th"
get_index = 1 = "st"
get_index = 2 = "nd"
get_index = 3 = "rd"
终于
在 math.stackexchange 上询问其背后的确切数学可能更好,或者如果有人知道添加评论或编辑我的答案会很好!
参考资料(这不是我的解决方案)
- Ordinal numbers replacement
- outputting ordinal numbers 1st,2nd,3rd
指南
你可以这样做:
for number in range(1, 114):
printedString = str(number)+' is the '+str(number)
if str(number) == '1' or (str(number)[-1] == '1' and str(number)[-2] != '1'):
printedString += 'st'
elif str(number) == '2' or (str(number)[-1] == '2' and str(number)[-2] != '1'):
printedString += 'nd'
elif str(number) == '3' or (str(number)[-1] == '3' and str(number)[-2] != '1'):
printedString += 'rd'
else:
printedString += 'th'
print(printedString+' number.')
所以,问题是 111
显示为 111st
而不是 111th
。
你有 11
作为 ex1
,我假设是“例外 1”的缩写,但你的情况:
if number == ex1:
显然不匹配 111
。
相反你可以这样做:
if number % 100 == ex1:
对于 11
、111
、211
等也是如此
旁注:
elif number % 10 == 1 or not ex1:
显然不是您想要的。这被解释为:
elif (number % 10 == 1) or (not ex1):
not ex1
不依赖于 number
并且总是以相同的方式求值 (False
)。但是,由于您已经在单独检查 ex1
,因此在此处正确执行此操作是多余的。
如果你想更正它,这样你就不需要检查 ex1
两次,你可以这样做:
if number % 10 == 1 and number % 100 != 11:
我认为在这种情况下使用 !=
比 not
更清楚,我认为将变量分配给 11
.
没有任何好处
请注意,11、12 和 13 具有第 th 个后缀。
另请注意,您可以更改 print
函数中的行尾(默认 \n
):
print('text', end=' ')
print('another text')
然后,我建议您使用 f"{data} constant text"
或 "{} constant text".format(data)
的格式化字符串。
这是我对你的问题的解决方案:
def getSuffix(n):
if n < 0: raise Exception("Ordinal negative numbers are not allowed")
if n % 100 in [11, 12, 13]: return 'th'
if n % 10 == 1: return 'st'
if n % 10 == 2: return 'nd'
if n % 10 == 3: return 'rd'
return 'th'
for number in range(1, 114):
print(f"{number} is the {number}{getSuffix(number)} number")
希望对您有所帮助。
我想动态地找到正确的序数根,例如:
111 = 111st
112 = 112nd
113 = 113rd ...
我尝试了其他解决方案,但找不到合适的解决方案。
这是我的代码:
for number in range(1, 114):
print(number)
ex1 = 11
ex2 = 12
ex3 = 13
if number == ex1:
print("is the " + str(number) + "th number.")
elif number % 10 == 1 or not ex1:
print("is the " + str(number) + "st number.")
elif number == ex2:
print("is the " + str(number) + "nd number.")
elif number % 10 == 2 or not ex2:
print("is the " + str(number) + "nd number.")
elif number == ex3:
print("is the " + str(number) + "rd number.")
elif number % 10 == 3 or not ex3:
print("is the " + str(number) + "rd number")
else:
print("is the " + str(number) + "th number.")
这是一个很好的解决方案:
ordinal = lambda n: "%d%s" % (n, "tsnrhtdd"[(n // 10 % 10 != 1) * (n % 10 < 4) * n % 10::4])
for number in range(1, 114):
print(f'the {ordinal(number)} number. :) ')
为人类编辑
注意:变量名称不适合在生产环境中使用,我试图更明确地说明 lambda 函数的每个步骤的作用!
def get_ordinal(n):
hacking_string = "tsnrhtdd" # 1)
is_num_divisible_by_ten = (n // 10 % 10 != 1) # 2)
is_num_reminder_0_3= (n % 10 < 4) # 3)
are_both_false_or_both_true= is_num_divisible_by_ten * is_num_between_0_3 # 4)
get_index = are_both_false_or_both_true* n % 10 # 5)
return f'{number}{hacking_string[get_index::4]}' #6) ---> starts at t | s | n | r
for number in range(1, 114):
print(f'the {get_ordinal(number)} number. :) ')
注意事项
找到的解决方案非常 Hacky 和聪明,我可能永远不会自己想出,正在使用一些聪明的数学技巧来找到数字的偏移集。 然而,根据要求,我简化了函数并添加了一些解释。
步骤 1. 这个字符串最好看成这个 "tsnr" "htdd" |左边是弦的“根”,右边是末尾。 (下面有更多解释)
第 2 步。
is_num_divisible_by_ten
--> 使用 floor division 结果为 True 或 False。第3步。
is_num_reminder_0_3
如果检查N和10的提醒是否在0和3之间,returns一个真/假标志。步骤 4.
are_both_false_or_both_true
乘以 2 bool 值,在 Python True 是 1,False 是 0,所以就像做 --> 1 * 0 . 只有当两个值都为真或都为假时,变量才为真,否则始终为假。第 5 步。
get_index
- > Returns 0 or 1 or 2 or 3.第 6 步。这里是 hacky 部分,使用从 get_index 接收到的索引,是使用
hacking_string
变量和 indexing-and-slicing:
get_index 值始终是以下之一:“tsnr”和采取的步骤 (4) 这些“rhtdd”中的任何一个,因此可能的组合是:
get_index = 0 = "th"
get_index = 1 = "st"
get_index = 2 = "nd"
get_index = 3 = "rd"
终于
在 math.stackexchange 上询问其背后的确切数学可能更好,或者如果有人知道添加评论或编辑我的答案会很好!
参考资料(这不是我的解决方案)
- Ordinal numbers replacement
- outputting ordinal numbers 1st,2nd,3rd
指南
你可以这样做:
for number in range(1, 114):
printedString = str(number)+' is the '+str(number)
if str(number) == '1' or (str(number)[-1] == '1' and str(number)[-2] != '1'):
printedString += 'st'
elif str(number) == '2' or (str(number)[-1] == '2' and str(number)[-2] != '1'):
printedString += 'nd'
elif str(number) == '3' or (str(number)[-1] == '3' and str(number)[-2] != '1'):
printedString += 'rd'
else:
printedString += 'th'
print(printedString+' number.')
所以,问题是 111
显示为 111st
而不是 111th
。
你有 11
作为 ex1
,我假设是“例外 1”的缩写,但你的情况:
if number == ex1:
显然不匹配 111
。
相反你可以这样做:
if number % 100 == ex1:
对于 11
、111
、211
等也是如此
旁注:
elif number % 10 == 1 or not ex1:
显然不是您想要的。这被解释为:
elif (number % 10 == 1) or (not ex1):
not ex1
不依赖于 number
并且总是以相同的方式求值 (False
)。但是,由于您已经在单独检查 ex1
,因此在此处正确执行此操作是多余的。
如果你想更正它,这样你就不需要检查 ex1
两次,你可以这样做:
if number % 10 == 1 and number % 100 != 11:
我认为在这种情况下使用 !=
比 not
更清楚,我认为将变量分配给 11
.
请注意,11、12 和 13 具有第 th 个后缀。
另请注意,您可以更改 print
函数中的行尾(默认 \n
):
print('text', end=' ')
print('another text')
然后,我建议您使用 f"{data} constant text"
或 "{} constant text".format(data)
的格式化字符串。
这是我对你的问题的解决方案:
def getSuffix(n):
if n < 0: raise Exception("Ordinal negative numbers are not allowed")
if n % 100 in [11, 12, 13]: return 'th'
if n % 10 == 1: return 'st'
if n % 10 == 2: return 'nd'
if n % 10 == 3: return 'rd'
return 'th'
for number in range(1, 114):
print(f"{number} is the {number}{getSuffix(number)} number")
希望对您有所帮助。