Python实现方便的读入数字

众所周知,python只能读字符串,你如果要读整数只能读一个字符串,split成列表,再用int或者float转换。
比如这样

s=input().split()
a,b=map(int,s)
#或者a,b=int(s[0]),int(s[1])

某种意义上复用性很低。
尤其是需要大量读入的竞赛题,或者实际开发中。

所以就会想着给他像比如c++一样,搞个cin>>x或者read(x)
但python没有>>,也不支持传址,所以就只能写
x=read()或者类似的形式。

//本文原作者XXOY

先直接放成品

1.非迭代器版本

def read():
    def get_numbers():
        try:#防止奇怪的东西出现
            read.s = input().split()
            read.s_len = len(read.s)
            if(read.s_len==0):get_numbers()#空行就继续
            read.cnt=0
            return 1#可以正常读
        except:#如果读到文件尾就不读了
            return 0
    if not hasattr(read, 'cnt'):
        if not get_numbers():return 0
    if read.cnt==read.s_len:
        if not get_numbers():return 0
    read.cnt+=1#下一个
    return eval(read.s[read.cnt-1])#用eval,整数与小数通用,改成int或许会更快一点
#本文原作者[XXOY](https://www.cnblogs.com/xxoy/)

2.迭代器版本

def read():
    def get_numbers():
        try:#防止奇怪的东西出现
            st=input()
            while st=='':st=input() #这行可以去掉,主要是防止空行报错
            read.s = map(eval,st.split()) #用eval,整数与小数通用,改成int或许会更快一点
            return 1#可以正常读
        except:#如果读到文件尾就不读了
            return 0
    if not hasattr(read, 's'):
        if not get_numbers():return 0
    try:
        return next(read.s)
    except StopIteration:
        if not get_numbers(): return 0
        else: return next(read.s)
#本文原作者[XXOY](https://www.cnblogs.com/xxoy/)

使用方法就直接



a,b,c=read(),read(),read()
print(a,b,c)

可以同一行输入,也可以跨行。

下面以非迭代器版本进行讲解。

首先,读入需要搞一个计数cnt,一个s(列表)用于存放数据。
用来记录当前读到的是哪一个值。

考虑到是这个变量所有read通用,所以搞一个类似静态变量的东西。
参考地址

然后写一个把字符串转化为数字列表的东西,写一个统计s中数字个数的东西。
考虑可能len(s)调用需要时间,就干脆再定义一个变量s_len,用于判定s是否到头。

def read():
    def get_numbers():
            read.s = list(map(eval,input().split())) #用eval,整数与小数通用,改成int或许会更快一点
            read.s_len = len(read.s)
            read.cnt=0

那就每一次调用就cnt++,返回s的对应位。

    read.cnt+=1#下一个,没找到python的++
    return read.s[read.cnt-1] #用eval,整数与小数通用,改成int或许会更快一点

如果s读完了,那就读下一个s
判断条件就是cnt==read.s_len。

if read.cnt==read.s_len:get_numbers()

其实到这就写完了,但考虑读入的不一定是很标准的数字,或者可能读到结尾了会RE。
于是再加入一个
try-except语句

最后聚合一下

#本文原作者[XXOY](https://www.cnblogs.com/xxoy/)
def read():
    def get_numbers():
        try:#防止奇怪的东西出现
            read.s = input().split()
            read.s_len = len(read.s)
            if(read.s_len==0):get_numbers()#空行就继续
            read.cnt=0
            return 1#可以正常读
        except:#如果读到文件尾就不读了
            return 0
    if not hasattr(read, 'cnt'):
        if not get_numbers():return 0
    if read.cnt==read.s_len:
        if not get_numbers():return 0
    read.cnt+=1#下一个
    return eval(read.s[read.cnt-1])#用eval,整数与小数通用,改成int或许会更快一点

最后的最后回答几个问题

1.Q:为什么用eval
A:为了照顾小数的情况,改成int或许更快

2.Q:为什么报错就返回0
A:因为我也不知道返回啥,返回0就相当于没读呗。

3.Q:迭代器和非迭代器时间复杂度一样吗
A:我觉得,看上去是迭代器更快,但有c++ Debug下那慢的要命的迭代器的前车之鉴,很可能最终是非迭代器更快,但差差不多,毕竟python你要什么速度吗~

4.未解决的问题:碰到中间出现字母的情况
解决方法:非迭代器版本最后一行使用read.s[cnt-1].isdigit()进行特判。
不加入进去主要是不知道你是要跳过还是怎么样。

好的终于结束了,本文原作者XXOY,有什么问题评论区提问,欢迎大家探讨。

posted @ 2021-07-12 22:05  箱庭  阅读(557)  评论(0编辑  收藏  举报