输入输出
Python 中的输入输出主要通过内置函数 input()
和 print()
完成,print()
的用法十分符合直觉:
>>> a = [1,2,3]; print(a[-1]) # 打印时默认末尾换行
3
>>> print(ans[0], ans[1]) # 可以输出任意多个变量,默认以空格间隔
1 2
>>> print(a[0], a[1], end='') # 令 end='', 使末尾不换行
1 2>>>
>>> print(a[0], a[1], sep=', ') # 令 sep=', ',改变间隔样式
1, 2
>>> print(str(a[0]) + ', ' + str(a[1])) # 输出同上,但是手动拼接成一整个字符串
算法竞赛中通常只涉及到基本的数值和字符串输出,以上用法基本足够,只有当涉及到浮点数位数时需要用到格式化字符串输出。格式化有三种方法,第一种也是最老旧的方法是使用 printf()
风格的 %
操作符;另一种是利用 format 函数,写起来比较长;第三种是 Python 3.6 新增的 f-string,最为简洁,但不保证考场中的 Python 版本足够新。详细丰富的说明可以参考 这个网页,尽管更推荐使用 format()
方法,但为了获得与 C 接近的体验,下面仅演示与 printf()
类似的老式方法:
>>> pi = 3.1415926; print('%.4f' % pi) # 格式为 %[flags][width][.precision]type
3.1416
>>> '%.4f - %8f = %d' % (pi, 0.1416, 3) # 右边多个参数用 () 括住,后面会看到其实是「元组」
'3.1416 - 0.141600 = 3'
input()
函数的行为接近 C++ 中的 getline()
,即将一整行作为字符串读入,且末尾没有换行符,但在算法竞赛中,常见的输入形式是一行输入多个数值,因此就需要使用字符串的 split()
方法并搭配列表推导式得到存放数值类型的列表,下面以输入 n 个数求平均值为例演示输入 n 个数得到「数组」的方法:
>>> s = input('请输入一串数字: '); s # 自己调试时可以向 input() 传入字符串作为提示
请输入一串数字: 1 2 3 4 5 6
'1 2 3 4 5 6'
>>> a = s.split(); a
['1', '2', '3', '4', '5', '6']
>>> a = [int(x) for x in a]; a
[1, 2, 3, 4, 5, 6]
>>> # 以上输入过程可写成一行 a = [int(x) for x in input().split()]
>>> sum(a) / len(a) # sum() 是内置函数
3.5
有时题目会在每行输入固定几个数,比如边的起点、终点、权重,如果只用上面提到的方法就只能每次读入数组然后根据下标赋值,这时可以使用 Python 的「拆包」特性一次赋值多个变量:
>>> u, v, w = [int(x) for x in input().split()]
1 2 4
>>> print(u,v,w)
1 2 4
题目中经常遇到输入 N 行的情况,可我们还没有讲最基本的循环语句,但 Python 强大的序列操作能在不使用循环的情况下应对多行输入,下面假设将各条边的起点、终点、权值分别读入三个数组:
>>> N = 4; mat = [[int(x) for x in input().split()] for i in range(N)]
1 3 3
1 4 1
2 3 4
3 4 1
>>> mat # 先按行读入二维数组
[[1, 3, 3], [1, 4, 1], [2, 3, 4], [3, 4, 1]]
>>> u, v, w = map(list, zip(*mat))
# *将 mat 解包得到里层的多个列表
# zip() 将多个列表中对应元素聚合成元组,得到一个迭代器
# map(list, iterable) 将序列中的元素(这里为元组)转成列表
>>> print(u, v, w) # 直接将 map() 得到的迭代器拆包,分别赋值给 u, v, w
[1, 1, 2, 3] [3, 4, 3, 4] [3, 1, 4, 1]
上述程序实际上相当于先读入一个 N 行 3 列的矩阵,然后将其转置成 3 行 N 列的矩阵,也就是外层列表中嵌套了 3 个列表,最后将代表这起点、终点、权值的 3 个列表分别赋值给 u, v, w。内置函数 zip() 可以将多个等长序列中的对应元素拼接在「元组」内,得到新序列。而 map()
其实是函数式编程的一种操作,它将一个给定函数作用于 zip()
所产生序列的元素,这里就是用 list()
将元组变成列表。你可以自行练习使用 *
和 zip(),map() 以理解其含义。需要注意的是 Python 3 中 zip()
和 map()
创建的不再返回列表而是返回迭代器,这里暂不解释它们之间的异同,你可以认为迭代器可以产生列表中的各个元素,用 list()
套住迭代器就能生成列表。