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,有什么问题评论区提问,欢迎大家探讨。