两年的平均数,写作[1858-60]。

14

有一些情况下,日期被写作“created ca. 1858-60”,人类读者会理解为“创建于约1858年至1860年之间”。

因此,请想象两个代表年份的整数。

a = 1858
b = 60

我希望能够得到a+b == 1859

我可以将它们解析为字符串,取前两个字符('18'),连接较短的字符串并将它们解析回数字,但这似乎有些绕弯子。

处理这个问题的Pythonic方式是什么?


5
对我来说,"60"似乎含义不明确,b的世纪前缀总是与a相同吗? - Cory Kramer
“规格”是什么?它也适用于三位数的年份吗? - Xetrov
@CoryKramer 是的,b始终与a共享前缀。 - Mitchell van Zuylen
@Goodra 不需要。 - Mitchell van Zuylen
12
我想澄清一下,您永远不需要处理1999-01这个日期吗? - Adam Smith
1
@AdamSmith。不,绝对不行。 - Mitchell van Zuylen
5个回答

23

我认为你的方法不太对。更简单的方法是将世纪添加到b中,然后使用它们作为普通数字,现在它们是可比较的。

def add_century(n: int, from_century=1900) -> int:
    """add_century turns a two-digit year into a four-digit year.

    takes a two-digit year `n` and a four-digit year `from_century` and
    adds the leading two digits from the latter to the former.
    """

    century = from_century // 100 * 100
    return century + n

然后你可以这样做:

a, b = 1858, 60
b = add_century(b, from_century=a)
result = (a + b) / 2
处理数字的方式有两个好处。
首先,您可以澄清可能存在的特殊情况。明确地将一个世纪加到另一个结束年份中,如果代码返回错误的结果,则非常清楚地说明了发生了什么。
其次,将对象转换为可比较的术语不仅是一个好主意,而且在某些“不太友好”的语言中是必需的,Python就是其中之一。快速转换使两个项目可以相互比较是确保您不会在以后混淆事情的简单方法。

这个答案在跨越世纪的边界时无法工作,并且结果是一个浮点数(在Python 3中)。 - Alex Taylor
4
@AlexTaylor明确表示他的代码永远不会跨越世纪边界,而我认为在此处使用浮点数结果是正确的,而OP没有指定。 - Adam Smith
整数可以在浮点数工作到过去很多年,所以浮点数是完全可以的。此外,这对于像1964-6这样的事情非常方便。 - corsiKa
1
我认为这是正确的方法,立即转换输入,明确表明你正在做出什么样的假设。但是,我会制作一个版本,即使它非常不可能,也可以正确解析1999-01,以避免将来可能发生的任何误解。我不认为有人会写1999-01表示“在1999年和1901年之间”。 - Jack V.
1
@PeterHansen 我不确定我是否更喜欢“平均”,但你说得对,“差异”在那里并没有太多意义。我更正为 result - Adam Smith
显示剩余3条评论

13

这个版本完全使用整数,并处理跨世纪的边界:

def year_range_average(a, b):
    return a + (b - (a % 100) + 100) % 100 // 2

>>> year_range_average(1858, 60)
1859
>>> year_range_average(1858, 61)
1859
>>> year_range_average(1858, 62)
1860
>>> year_range_average(1898, 2)
1900

1
使用正则表达式(例如(dd))解析字符串,获取XXYY-ZZ组,这些将存储为g1、g2和g3。
result = int(g1) * 1000 + (int(g2) + int(g3))/2

当然,这假设前缀始终相同。因此,1890-10将会出错...
它还假设前缀总是存在。
总的来说,进行字符串拼接和平均似乎更好...

1

try this:

a = 1858
b = 60

def average_year(a,b):
    c = int(str(a)[:2]) * 100
    a1 = int(str(a)[2:])
    return c + (b + a1)/2

print average_year(a,b)
> 1859

0

嗯,如果你不想转换成字符串...那我们来做一些数学运算:

a = 1858
b = 60
cent = 0
s = 0
if a < 2000:
    s = a - 1000
    c, y = divmod(s, 100)
    cent = 1000
else:
     s = a - 2000
     cent = 2000
     c, y = divmod(s, 100)
avg = (b + y) / 2
result = cent + (c*100) + avg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接