【问题标题】:Splitting a string to do some math yields strange result, in Python在 Python 中拆分字符串以进行一些数学运算会产生奇怪的结果
【发布时间】:2012-02-13 17:58:39
【问题描述】:

所以我承认这是一项家庭作业,但我并不是要你们所有人为我做这件事,我只是在寻求一些指导。我们需要让 Python 程序在单个字符串中接受 Hours:Minutes (2:30) 格式的时间,并以分钟为单位输出时间量。 (即 2 小时 30 分钟 = 150 分钟)

我仍然需要解决字符串输入的一些限制:

  1. 确保它只使用数字和冒号
  2. 确保它只能接受五个字符 (##:##)
  3. 确保中间字符是冒号(即数字的顺序正确)
  4. 并确保如果输入像 4:35 这样的时间,会在前面自动添加一个零

我稍后会处理这个问题——现在我决定处理从输入中得到的数学。

对我来说,将字符串分成两部分是有意义的:小时和分钟。然后,我将小时数乘以 60,并将它们添加到预先存在的分钟数中以获得总分钟数。 However, right now, entering a time like 02:45 is outputting a minute amount of 02020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020245.

知道这里可能出了什么问题吗?需要说明的是,这是作业,我想自己解决输入限制,我只需要帮助解决这个数学问题。

#Henry Quinn - Python Advanced 4.0 Hours and Minutes
import re
print "This program takes an input of time in hours and minutes and outputs the amount    of minutes."
count = 0

#I still need to work out while loop
#Supposed to make sure that a time is entered correctly, or error out
while (count <1):
    time = raw_input("Please enter the duration of time (ex: 2:15 or 12:30): ")
    if not re.match("^[0-9, :]*$", time):
        print "Sorry, you're only allowed to use the numbers 0-9."
    elif len(time) > 5:
        print "Sorry, only five characters max allowed."
#MAKE THIS CHECK FOR A COLON
#elif
#elif
    else:
        count = count + 1

#If time = 12:45, hours should be equal to 12, and minutes should be equal to 45
hours = time[:2]
minutes = time[3:]

#Should convert hours to minutes
newhours = hours * 60

#Should make total amount of minutes
totalminutes = newhours + minutes

print "The total amount of elapsed minutes is %s" % (totalminutes)

raw_input("Please press Enter to terminate the program.")

【问题讨论】:

  • 将一个字符串乘以一个整数会生成一个包含许多原始字符串副本的字符串。先在数字字符串上调用int()

标签: python string math string-split


【解决方案1】:

现在,小时和分钟是字符串变量,而不是整数。因此,您不能像乘数一样将它们相乘。

将第 20 和 21 行更改为

hours = int(time[:2])
minutes = int(time[3:])

并且输入 02:45 应该会起作用。但是,如果您没有前导 0(例如,如果您输入 2:45),您仍然会遇到问题,所以我建议您改为将其拆分为“:”,如下所示:

hours = int(time.split(":")[0])
minutes = int(time.split(":")[1])

【讨论】:

  • hours, minutes = map(int, time.split(':'))
  • 是的,我担心会漏掉时间输入的前导数字。让我试试这个并回复你。
  • @StevenRumbalski:当然,我只是保持语法简单,因为我知道他是 Python 新手
  • @DavidRobinson:我同意你采用了最好的方法。
  • @HenryEdwardQuinnIV:是的(它会做和我的代码一样的事情)
【解决方案2】:

您正在将字符串与整数相乘。

>>> st = '20'
>>> st*3
'202020'
>>> int(st)*3
60
>>>

类型转换为int

所以,改变这个

minutes = time[3:]
newhours = hours * 60

 minutes = int(time[3:])
 newhours = int(hours) * 60

【讨论】:

  • 其他人也告诉我这个。非常感谢。
【解决方案3】:

因为这是家庭作业,所以这里有一个解决方案 - 如果你弄清楚它是如何工作的,我保证你会学到一些新东西 ;)

tre = re.compile("([0-2]?[0-9]):([0-5][0-9])")
h,m = ((int(_) for _ in tre.match("2:30").groups())
td = timedelta(hours=h, minutes=m)
print(td.total_seconds() / 60)

【讨论】:

  • 我已经得到了我需要的答案,但我会试着弄清楚你的帖子,以便给我的教授留下深刻印象。我只是想让它知道我不知道什么是正则表达式;只是碰巧在谷歌搜索时偶然发现了它们。目前正在学习我的第一语言。
  • 我不确定编译它实际上做了什么,但它似乎将时间中的每个数字限制在一定范围的数字之间。不过,你给我的第一个数字是 0-2,所以这似乎也可以用于军事时间。然后 tre.match 是否使用冒号作为中位数分割字符串?
  • 正则表达式的神奇之处在于括号() - 它们创建_group_s - 所以在实践中,它与使用分号作为分隔符分割字符串的作用相同。
【解决方案4】:

第 2 项和第 4 项要求相互矛盾。要么只接受 5 个字符的字符串,要么也允许 #:##(4 个字符的形式)。

import re

def minutes(timestr):
    """Return number of minutes in timestr that must be either ##:## or #:##."""
    m = re.match(r"(\d?\d):(\d\d)$", timestr)
    if m is None:
       raise ValueError("Invalid timestr: %r" % (timestr,))
    h, m = map(int, m.groups())
    return 60*h + m

如果您在timestr##:##:# 等表单中允许空格,则:

def minutes2(timestr):
    h, m = map(int, timestr.partition(':')[::2])
    return 60*h + m

如果您想将小时限制为 0..23,分钟限制为 0..59,那么:

import time

def minutes3(timestr):
    t = time.strptime(timestr, "%H:%M")
    return 60*t.tm_hour + t.tm_min

Example

minutes ('12:11') -> 731
minutes2('12:11') -> 731
minutes3('12:11') -> 731
minutes ('  12:11') -> error: Invalid timestr: '  12:11'
minutes2('  12:11') -> 731
minutes3('  12:11') -> error: time data '  12:11' does not match format '%H:%M'
minutes ('12:11  ') -> error: Invalid timestr: '12:11  '
minutes2('12:11  ') -> 731
minutes3('12:11  ') -> error: unconverted data remains:   
minutes ('3:45') -> 225
minutes2('3:45') -> 225
minutes3('3:45') -> 225
minutes ('03:45') -> 225
minutes2('03:45') -> 225
minutes3('03:45') -> 225
minutes ('13:4') -> error: Invalid timestr: '13:4'
minutes2('13:4') -> 784
minutes3('13:4') -> 784
minutes ('13:04') -> 784
minutes2('13:04') -> 784
minutes3('13:04') -> 784
minutes ('24:00') -> 1440
minutes2('24:00') -> 1440
minutes3('24:00') -> error: time data '24:00' does not match format '%H:%M'
minutes ('11:60') -> 720
minutes2('11:60') -> 720
minutes3('11:60') -> error: unconverted data remains: 0

【讨论】:

  • 我的程序正在使用另一个答案。您能否详细介绍一下如何在我现有的代码中实现 minutes2?
  • minutes2 是一个函数。调用它以获得结果:minutes2('12:11') 或在您的情况下为totalminutes = minutes2(time)。您的具体问题("1"*21*2)在其他答案中有所介绍。我的回答表明,您给出的要求是矛盾的('##:##' 与 '#:##')且不完整(未指定小时、分钟的允许范围)。每个功能minutes() 遵循的要求略有不同。
猜你喜欢
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多