Python

目录

  1. Python安装
    LeetCode
    Atcoder
    Codeforces
  2. Python输出
    Python读入
    Python条件
  3. Python字符串
  4. Python类型 实数,字符串格式化
    Python操作符
  5. Python循环
  6. Python列表
  7. 循环控制 continue break else
  8. Python函数
  9. Python集合
  10. Python字典
  11. Python模块
  12. Python文件
  13. Python面向对象编程
  14. Python作用域
  15. Python异常
  16. sortedcontainers
  17. requests
  18. matplotlib

安装

Python

https://www.python.org/downloads/release/python-3105/
下载
Windows installer (64-bit) Windows Recommended 9a99ae597902b70b1273e88cc8d41abd 28637720
安装时选上 Add Python.exe to PATH

Linux 和 Mac 系统自带 Python 但可能不是最新版本

如果Windows系统太旧,无法安装最新的Python可以试一试旧版的Python
https://www.python.org/downloads/release/python-368/
选择
Windows x86-64 executable installer Windows for AMD64/EM64T/x64

PyCharm

https://www.jetbrains.com/pycharm/download/
下载 Community 版

基本概念

使用 Python

交互模式(interactive mode)
脚本模式(script mode)

变量 variable

变量名必须以字母或下划线开始
由数字字母下划线组成
不能是关键字
区分大小写

input() 读入一行一个字符串

s = input()

int 将字符串转换成整数

n = int(input())
print('Hello World')

return 返回

在函数中返回 return

常见运算

加法 +
减法 -
乘法 *
实数除法 / 3/2=1.5(除法商是实数)
整数除法 // 3//2=1(除法下取整)
取模(除法余数) %
乘方 **
无论多少层括号嵌套,都用小括号,中括号和大括号有其他的含义

运算赋值

a+=b 相当于 a=a+b
-=
*=
/=
//=
**=

Python 没有 C++ 和 Java 的 ++ 和 --

练习题

https://leetcode.com/problems/add-two-integers/
https://codeforces.com/problemset/problem/630/A
https://atcoder.jp/contests/abc172/tasks/abc172_a

其他题目

https://leetcode.com/problems/divisor-game/
https://atcoder.jp/contests/abc043/tasks/abc043_a
https://atcoder.jp/contests/abc045/tasks/abc045_a
https://atcoder.jp/contests/abc055/tasks/abc055_a
https://atcoder.jp/contests/abc084/tasks/abc084_a
https://atcoder.jp/contests/abc089/tasks/abc089_a
https://atcoder.jp/contests/abc134/tasks/abc134_a
https://atcoder.jp/contests/abc140/tasks/abc140_a
https://atcoder.jp/contests/abc145/tasks/abc145_a
https://atcoder.jp/contests/abc178/tasks/abc178_a
https://atcoder.jp/contests/abc198/tasks/abc198_a
https://codeforces.com/problemset/problem/630/A

除法取整的妙用

https://atcoder.jp/contests/abc157/tasks/abc157_a
https://atcoder.jp/contests/abc200/tasks/abc200_a

计算 A除以B上取整
Python和C++通用 (A+B-1)//B
Python可用-(A//-B)

map(int, input().split())

读入一行多个整数可以写

a, b = map(int, input().split()) # 读入一行两个整数
a, b, c = map(int, input().split()) # 读入一行三个整数
a, b, c, d = map(int, input().split()) # 读入一行四个整数

a = int(input()) # 读入一行一个整数
a, = map(int, input().split()) # 读入一行一个整数 注意 逗号!
a = map(int, input().split()) # 错误写法

min max

print(min(a, b)) # 输出 a 和 b 的较小值
print(min(a, b, c)) # 输出 a, b, c 三个数的的最小值
print(max(a, b)) # 输出 a 和 b 的较大值
print(max(a, b, c)) # 输出 a, b, c 三个数的的最大值

print(min('aaa', 'bb', 'c', key=len)) # 输出3个字符串中最短的一个
print(max('aaa', 'bb', 'c', key=len)) # 输出3个字符串中最长的一个

多对多赋值

Python允许多对多同时赋值
比如

x, y = y, x # 交换 x 和 y 的值

Python条件

Python操作符

练习题

学会 if 之后, 不涉及字符串和浮点数的 abc a 题都可以做了

https://atcoder.jp/contests/abc080/tasks/abc080_a
https://atcoder.jp/contests/abc086/tasks/abc086_a
https://atcoder.jp/contests/abc098/tasks/abc098_a
https://atcoder.jp/contests/abc100/tasks/abc100_a
https://atcoder.jp/contests/abc104/tasks/abc104_a
https://atcoder.jp/contests/abc106/tasks/abc106_a
https://atcoder.jp/contests/abc107/tasks/abc107_a
https://atcoder.jp/contests/abc113/tasks/abc113_a
https://atcoder.jp/contests/abc114/tasks/abc114_a
https://atcoder.jp/contests/abc116/tasks/abc116_a
https://atcoder.jp/contests/abc127/tasks/abc127_a
https://atcoder.jp/contests/abc130/tasks/abc130_a
https://atcoder.jp/contests/abc133/tasks/abc133_a
https://atcoder.jp/contests/abc137/tasks/abc137_a
https://atcoder.jp/contests/abc148/tasks/abc148_a
https://atcoder.jp/contests/abc150/tasks/abc150_a
https://atcoder.jp/contests/abc152/tasks/abc152_a
https://atcoder.jp/contests/abc153/tasks/abc153_a
https://atcoder.jp/contests/abc155/tasks/abc155_a
https://atcoder.jp/contests/abc156/tasks/abc156_a
https://atcoder.jp/contests/abc159/tasks/abc159_a
https://atcoder.jp/contests/abc164/tasks/abc164_a
https://atcoder.jp/contests/abc169/tasks/abc169_a
https://atcoder.jp/contests/abc174/tasks/abc174_a
https://atcoder.jp/contests/abc181/tasks/abc181_a
https://atcoder.jp/contests/abc194/tasks/abc194_a

https://atcoder.jp/contests/abc034/tasks/abc034_b

https://codeforces.com/problemset/problem/1/A
https://codeforces.com/problemset/problem/4/A
https://codeforces.com/problemset/problem/50/A
https://codeforces.com/problemset/problem/486/A
https://codeforces.com/problemset/problem/617/A

字符串

字符

Python 不区分 字符 和 长度为1的字符串,这个和 C++ Java 不同

ASCII

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。
它主要用于显示现代英语

把一些字符对应到 0~127 的数字
控制字符 0~31
空格 32
数字 48~57
大写字母 65~90
小写字母 97~122

print(ord('A'))  # 65
print(chr(65))  # A

转义字符 '\n' 换行 '\t' 制表符

字符串基本操作

完整详细的文档可以参考
https://docs.python.org/3/library/stdtypes.html#string-methods

s = input()  # 读入一行一个字符串,不读入换行符
a, b = input().split()  # 读入一行(用空白分开的)两个字符串
a, b, c = input().split()  # 读入一行(用空白分开的) 三个字符串
print(s)  # 输出字符串
print(1, 'b', sep='')  # 输出两个变量,中间不加空格
print(1, end='')  # 输出之后不要换行

print(len(s))  # 字符串求长度
print(s + s)  # +表示字符串连接
print(s * 2)  # *表示字符串重复2次
print(s[0])  # 输出字符串最左的字符,注意下标从 0 开始
print(s[-1])  # 输出字符串最右的字符,下标使用中括号 []
# s = 'ABC'
#      A     B     C
#    s[0]  s[1]  s[2]
#   s[-3] s[-2] s[-1]

print(s[2:8])  # 字符串切片,s[a:b]表示从 s[a] 到 s[b-1] 不包括 s[b]
print(s[2:8:2])  # 字符串切片,s[a:b:c]表示从 s[a] s[a+c] s[a+2*c] ... 不包括 s[b]
# 其中 a 和 b 都可以省略
# 其中 c 可以为负数,表示倒序
print(s[::-1])  # 前后翻转输出字符串s

print('a' in 'aaa')  # 查找子串是否出现过
print('b' in 'aaa')  # 查找子串是否出现过
print('a' not in 'aaa')  # 查找子串是否出现过
print('b' not in 'aaa')  # 查找子串是否出现过

print('aaa'.find('a'))  # 查找子串位置,没出现过返回-1
print('aaa'.find('b'))  # 查找子串位置,没出现过返回-1
print('aaa'.index('a'))  # 查找子串位置,没出现过报错
print('aaa'.index('b'))  # 查找子串位置,没出现过报错

print(str(1) + str(1))  # 数字转字符串,用 str
print(int('1') + int('1'))  # 字符串数字,用 int

print('11' < '2')  # 字典序可以直接使用 比较运算符
# 字典序
# 两个字符串按字典序比较,从左向右找到一个不同的字符进行比较,比如 'abc' < 'abd'
# 如果其中一个字符串是另一个字符串的前缀,那么短的字典序比较小,比如 'ab' < 'abc'
# 也可以认为每个字符串后有一个结束字符,比任何字符都小 'ab_' < 'abc_'
print(eval('2**1000'))  # 表达式求值 eval
print('a b c'.replace(' ',','))  # 把空格替换为逗号
# isupper islower isalpha isdigit 判断是否是大写,小写,字母,数字
# upper lower swapcase 转大写 小写 大小写互换
# strip lstrip rstrip
# startswith endswith 判断开始结尾

print('aaa'.count('a')) # 计算 'aaa' 包含 'a' 几次

# 数字和字符串不相等
if '2' == 2:
    print("'2' == 2")
else:
    print("'2' != 2")

转字符串时 repr 和 str 的区别

对整数和浮点数没区别,对字符串来说,repr会帮你加上引号和转义

字符

https://atcoder.jp/contests/abc013/tasks/abc013_1 A
https://atcoder.jp/contests/abc049/tasks/abc049_a UOIAUAI
https://atcoder.jp/contests/abc151/tasks/abc151_a Next Alphabet
https://atcoder.jp/contests/abc171/tasks/abc171_a αlphabet
https://atcoder.jp/contests/abc252/tasks/abc252_a ASCII code
https://atcoder.jp/contests/abc257/tasks/abc257_a A to Z String 2

字符串

https://atcoder.jp/contests/abc048/tasks/abc048_a AtCoder *** Contest
https://atcoder.jp/contests/abc051/tasks/abc051_a Haiku
https://atcoder.jp/contests/abc068/tasks/abc068_a ABCxxx
https://atcoder.jp/contests/abc132/tasks/abc132_a Fifty-Fifty
https://atcoder.jp/contests/abc146/tasks/abc146_a Can't Wait for Holiday
https://atcoder.jp/contests/abc166/tasks/abc166_a A?C
https://atcoder.jp/contests/abc175/tasks/abc175_a Rainy Season
https://atcoder.jp/contests/abc179/tasks/abc179_a Plural Form
https://atcoder.jp/contests/abc197/tasks/abc197_a Rotate
https://atcoder.jp/contests/abc215/tasks/abc215_a Your First Judge
https://atcoder.jp/contests/abc217/tasks/abc217_a Lexicographic Order 字典序
https://atcoder.jp/contests/abc218/tasks/abc218_a Weather Forecast
https://atcoder.jp/contests/abc224/tasks/abc224_a Tires
https://atcoder.jp/contests/abc232/tasks/abc232_a QQ solver 先replace再eval
https://atcoder.jp/contests/abc219/tasks/abc219_b Maritozzo replace的用法

可以用string也可以用int

https://atcoder.jp/contests/abc073/tasks/abc073_a September 9
https://atcoder.jp/contests/abc162/tasks/abc162_a Lucky 7
https://atcoder.jp/contests/abc187/tasks/abc187_a Large Digits

复杂的题目

https://atcoder.jp/contests/abc175/tasks/abc175_a Rainy Season
https://atcoder.jp/contests/abc216/tasks/abc216_a Signed Difficulty
https://atcoder.jp/contests/abc225/tasks/abc225_a Distinct Strings
https://atcoder.jp/contests/abc229/tasks/abc229_a First Grid

浮点数

IEEE754
Python的浮点数和C++,Java的浮点数是一样
是二进制的科学计数法
在二进制下0.1不是有限小数,是无限循环小数

浮点数之间的运算

print(float(1), float('1.2')) # float 可以把整数和字符串转成 float
print(int(1.9), int(-1.9)) # int 可以把 float 转成 int,结果向零取整
a = 2 ** 54 + 2
print(a / 2, int(a / 2), a // 2) # 整数之间用 / 进行运算会得到浮点数
a = 1
b = 0.1
print(a + b, a - b, a * b, a / b, a // b) # 两个操作数中有一个是浮点数,结果就是浮点数
print(a / b, int(a / b), a // b, int(a // b)) # 注意区别 int(a / b) 不等价于 (a // b)
print(0.1 + 0.2) # 有误差
print(0.1 * 0.1) # 有误差

# 格式化输出,以下三种写法等价
print('%0.f' % 1.5) # 最初写法
print('{:.0f}'.format(1.5)) # 从 Python 2.6 开始,之后我会使用这种写法
print(f'{1.5:.0f}') # 从 Python 3.6 开始

print('{:.0f} {:.0f} {:.0f} {:.0f} {:.0f} {:.0f}'.format(-2.5, -1.5, -0.5, 0.5, 1.5, 2.5)) # 舍入到偶数
a = 0.0
print(a, -a) # 注意 -0.0
print('{:04d}'.format(1)) # 输出整数用d,4表示占4个位置,0表示不足4位高位补0



a, b, c = input().split() # 如果需要读入一行中不同的类型,必须先按字符串读入
b = int(b) # 每一个变量再转成自己需要的类型
c = float(c)
print(type(a)) # 输出变量的类型
print(type(b))
print(type(c))
print(a, b, c)

# 科学计数法,e 多少就是乘以10的多少次方
# 1e-3 = 0.001
# 1e3 = 1000
# 10e5 = 1000000

# Python中浮点数,整数部分如果是0可以省略,小数部分如果是0可以省略,不能同时省略
# 0.0 浮点数0
# 0.  浮点数0
# .0  浮点数0
# .   错误写法


# help(round)
# 查看函数帮助 当然直接 Google 文档 肯定更详细

import math #
print(math.sqrt(100)) # 使用 sqrt 时需要 math.

from math import * # import math 中的所有函数
print(sqrt(100)) # 使用 sqrt 时省略 math.


import random
print(random.randint(1, 259)) # 随机一个 1 到 259 的数字

格式化输出参考文档
https://docs.python.org/3/library/stdtypes.html#old-string-formatting
https://docs.python.org/3/library/string.html#string.Formatter
https://docs.python.org/3/reference/lexical_analysis.html#f-strings

其他文档
https://realpython.com/python-f-strings/
https://mlln.cn/2018/05/19/python3 f-string格式化字符串的高级用法/

查看自己的做题情况
https://kenkoooo.com/atcoder/

我写的 atcoder 简要翻译
https://wwwwodddd.com/atcoder.html

实数练习题

https://atcoder.jp/contests/abc030/tasks/abc030_b
https://atcoder.jp/contests/abc142/tasks/abc142_a
https://atcoder.jp/contests/abc163/tasks/abc163_a
https://atcoder.jp/contests/abc193/tasks/abc193_a
https://atcoder.jp/contests/abc205/tasks/abc205_a
https://atcoder.jp/contests/abc211/tasks/abc211_a
https://atcoder.jp/contests/abc206/tasks/abc206_a
https://atcoder.jp/contests/abc231/tasks/abc231_a
https://atcoder.jp/contests/abc242/tasks/abc242_a

难题

https://atcoder.jp/contests/abc196/tasks/abc196_b
https://atcoder.jp/contests/abc169/tasks/abc169_c

sqrt的使用

https://atcoder.jp/contests/abc077/tasks/abc077_b sqrt
https://atcoder.jp/contests/abc246/tasks/abc246_b sqrt
https://atcoder.jp/contests/abc086/tasks/abc086_b sqrt

简单计数题

https://atcoder.jp/contests/abc046/tasks/abc046_b

循环 while 和 for in

Python 没有 do while 循环

range(n) # 起点是0,终点是n-1,公差是1,共n个数字
range(s, t) # 起点是s,终点是t-1,公差是1,共t-s个数字
range(s, t, d) # 起点是s,终点<t,公差是d,共(t-s) // d个数字
for i in range(10):
    print(i)
for i in range(5, 10):
    print(i)
for i in range(2, 10, 2):
    print(i)

for i in range(4, -1, -1): # 倒序输出 4 3 2 1 0
    print(i)
for i in range(5)[::-1]: # 倒序输出 4 3 2 1 0
    print(i)


# for ... in ... 一定一起用

i = 0
# 当条件成立时,反复运行 while 中的语句,第一次运行之前也检查条件是否成立
while i < 10:
    print(i)
    i += 1

# 循环可以嵌套
# 每嵌套一层就要缩进一层
for i in range(2):
    for j in range(2):
        for k in range(2):
            for l in range(2):
                print(i, j, k, l)
# 没有办法让缩进次数更少(我建议缩进用4个空格,虽然可以改成1个空格)
# 之后学习函数和递归,可以减少一些缩进

pass # pass 表示什么都不做,比如 if while for 

阶乘

n! = 1 * 2 * 3 * ... * n
0! = 1
1! = 1
2! = 1 * 2 = 2
3! = 1 * 2 * 3 = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320

取模

(a + b) % p == (a % p + b % p) % p
(a - b) % p == (a % p - b % p) % p
(a * b) % p == (a % p * b % p) % p
(a / b) % p 需要用乘法逆元


(12 // 2) % 7 = 6
(12 % 7) // (2 % 7) = 5 / 2
如果模数和除数互质,那么可以用乘法逆元解决这个问题

Python 2 和 3 的区别

Python 2
raw_input() 读入一行一个字符串

Python 3
input()

Python 2
input() 读入一个字符串并求值

Python 3 删掉了这个函数
eval(input())


Python 2
print 123 不用加括号

Python 3
print(123) 需要加括号


Python 2
print(3/2) 整数写 /// 都表示整数除法

Python 3 / 是实数除法 // 是整数除法

AC Accepted

程序正常结束,结果正确(有的时候正确输出不是唯一的)

WA Wrong Answer

程序正常结束,但是结果不对

RE Runtime Error

程序运行出错,常见错误,数组越界,除以零,递归层数太多

TLE Time Limit Exceeded

计算机运行的速度不是无限快的
如果自己的做法比较慢,会超时

如何测试程序运行时间,以后讲
简单来说就是自己大概看表测一下

或者是估算一下 基本操作 的次数
什么是基本操作?

https://atcoder.jp/contests/abc238/tasks/abc238_a

循环练习题

https://atcoder.jp/contests/abc055/tasks/abc055_b 阶乘
https://atcoder.jp/contests/abc058/tasks/abc058_b
https://atcoder.jp/contests/abc076/tasks/abc076_b
https://atcoder.jp/contests/abc090/tasks/abc090_b
https://atcoder.jp/contests/abc093/tasks/abc093_b
https://atcoder.jp/contests/abc189/tasks/abc189_b Alcoholic
https://atcoder.jp/contests/abc190/tasks/abc190_b Magic 3
https://atcoder.jp/contests/abc191/tasks/abc191_b Remove It
https://atcoder.jp/contests/abc193/tasks/abc193_b Play Snuke
https://atcoder.jp/contests/abc200/tasks/abc200_b 200th ABC-200
https://atcoder.jp/contests/abc203/tasks/abc203_b AtCoder Condominium
https://atcoder.jp/contests/abc204/tasks/abc204_b Nuts
https://atcoder.jp/contests/abc206/tasks/abc206_b Savings
https://atcoder.jp/contests/abc207/tasks/abc207_b Hydrate
https://atcoder.jp/contests/abc215/tasks/abc215_b log2(N)

https://codeforces.com/contest/1703/problem/A
https://codeforces.com/contest/1692/problem/A
https://codeforces.com/contest/1676/problem/A
https://codeforces.com/contest/1669/problem/A

列表

Python 的列表中存储的元素不区分类型,可以是 int str float 或者是list

a = [1, 'a', 1.1, [2]] # 初始化一个列表
a.append(1) # 在末尾添加一个元素

print(a[0]) # 输出列表第一个元素
print(a[-1]) # 输出列表最后一个元素
print(a[::-1]) # 倒序输出列表 和字符串类似
print(len(a)) # 输出列表的长度

# 初始化长度为 n 的列表
a = [0 for i in range(n)]
a = [0] * n # 对于 0 可以这样初始化

s = 'abc'
# s[1] = '0'
a = list(s)  # 字符串转列表
print(a)
a[1] = '0'
print(a)
s = ''.join(a) # 将列表 a 中的字符串连接起来,以''作为分隔
print(s)
s = ','.join(a) # 将列表 a 中的字符串连接起来,以','作为分隔
print(s)
b = s.split(',') # 按','把 s 分成若干段,结果是一个列表
print(b)

print('a,,b,,c'.split(',')) # split 的结果可能有空字符串
print('a  b  c'.split(' ')) # split 的结果可能有空字符串
print('a  b  c'.split()) # 按空白分开,并去掉空串的结果

a = [1, 2, 3]
print(max(a)) # 求列表最大值
print(min(a)) # 求列表最小值
print(sum(a)) # 求列表所有数字的和
print(a.index(2)) # 查找第一个2出现的位置

a = list(map(int, input().split()))
# 读入一行若干个数字,必须加 list !


a = [5, 6, 7]
for i in range(len(a)):
    print(a[i])

for i in a:
    print(i)


for i in 'abc': # for in 后可以接字符串
    print(i)



a = list(str(123))
print(a) # 数字转字符串转列表

a = [4, 2, 3, 1]
b = sorted(a) # 排序,默认升序
print(b) # 输出排序之后的 a (并不修改 a
print(a)

b = a.sort() # 排序 a,没有返回值
print(b) # None
print(a) # 排序好的结果

print(sorted(a, reverse=True)) # 排序,降序
a.sort(reverse=True) # 排序,降序
print(a)

n = 3
a = [3, 1, 2]
# 先枚举i,再枚举j,保证 i < j
for i in range(n):
    for j in range(i + 1, n):
        a[i] * a[j]

for j in range(n):
    for i in range(j):
        a[i] * a[j]


print([1, 1, 2].count(1)) # 计算列表中有多少个等于1的数字



b = a # 让 b 也指向 a 指向的列表
b.append(2) # b 中添加一个元素
print(a) # b 添加一个元素,也会改变 a

b = a.copy() # 让 b 指向 a 的复制
b = a[:] # 上一句话也可以这样写
b.append(3) # 修改 b 不会修改 a
print(a) # a 不会改变



print([1, 1] < [2]) # 列表比较大小,从第一个元素开始依次比较,如果相同比较下一个


# 二维数组
a = [[0 for j in range(m)] for i in range(n)]
a = [[0] * m] * n # 错误的二维数组初始化

# 通过 key=函数 控制排序的比较方式
def unit(x):
    return (x % 10, x // 10)
print(max(13, 22, 31, key=unit))
a = [87, 78, 56, 65, 41, 14, 23, 32]
a = range(100)
print(sorted(a, key=unit))

https://atcoder.jp/contests/abc143/tasks/abc143_b
(a + b + c) * (a + b + c) = 9项
= a * a + a * b + a * c + b * a + b * b + b * c + c * a + c * b + c * c
= (a * a + b * b + c * c) + 2 * (a * b + a * c + b * c)


a * b + a * c + b * c = ((a + b + c) * (a + b + c) - (a * a + b * b + c * c)) / 2
答案 = (和的平方 - 平方和) // 2

https://atcoder.jp/contests/abc088/tasks/abc088_b
如果只有一个数字 d
先手 - 后手 = (d - 0)

如果有两个数字 d c  (d < c)
先手拿 c
后手拿 d
先手 - 后手 = c - (d - 0)

如果有三个数字 d c b  (d < c < b)
先手拿 b
后手面对 d c 的局面,可以比先手多 c - d
先手 - 后手 = b - (c - (d - 0))

如果有四个数字 d c b a (d < c < b < a)
先手拿 a
后手面对 d c b 的局面,可以比先手多 b - (c - d)
先手 - 后手 = a - (b - (c - (d - 0)))



数组练习题

https://atcoder.jp/contests/abc161/tasks/abc161_b Popular Vote
https://atcoder.jp/contests/abc151/tasks/abc151_b Achieve the Goal
https://atcoder.jp/contests/abc143/tasks/abc143_b TAKOYAKI FESTIVAL 2019
https://atcoder.jp/contests/abc142/tasks/abc142_b Roller Coaster
https://atcoder.jp/contests/abc135/tasks/abc135_b 0 or 1 Swap
https://atcoder.jp/contests/abc130/tasks/abc130_b Bounding
https://atcoder.jp/contests/abc127/tasks/abc127_b Algae
https://atcoder.jp/contests/abc124/tasks/abc124_b Great Ocean View
https://atcoder.jp/contests/abc115/tasks/abc115_b Christmas Eve Eve
https://atcoder.jp/contests/abc114/tasks/abc114_b
https://atcoder.jp/contests/abc112/tasks/abc112_b
https://atcoder.jp/contests/abc110/tasks/abc110_b
https://atcoder.jp/contests/abc088/tasks/abc088_b
https://atcoder.jp/contests/abc081/tasks/abc081_b
https://atcoder.jp/contests/abc079/tasks/abc079_b
https://atcoder.jp/contests/abc062/tasks/abc062_b

循环控制 break continue else

i = 0
while True:
    print(i)
    i += 1
    if i == 10:
        break # 跳出 1 层循环
else:
    print('BREAK')

for i in range(10):
    if i % 2 == 1:
        continue # 立即进入下一次循环
    print(i)
else:
    print('NO_BREAK')

# for 和 while 可以带 else
# 如果循环是正常结束的,运行 else 中的代码
# 如果循环不是正常结束的(被break的)不运行 else 的代码

map的实现细节

s = '12 34 56'
a = s.split()

# a = [a[0], a[1], a[2]]
# list(map(int, a)) = [int(a[0]), int(a[1]), int(a[2])]
print(a)
print(list(map(int, a)))

print(list(map(int, '123456789')))
exit() # 直接结束程序,之后的代码都不运行了


a = (map(int, input().split()))
print(a)
for i in a: # 如果不加 list 当我们循环 a 的时候,才会真正调用 int
    print('FIRST', i)
for i in a: # 如果不加 list 这个循环是不运行的
    print('SECOND', i)
exit()

a = list(map(int, input().split()))
# 如果 map 的结果需要反复使用,先转成 list
# 如果 只使用一次,转不转都可以
print(a)
for i in a:
    print('FIRST', i)
for i in a:
    print('SECOND', i)
exit()


a = map(int, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

for i in a:
    print(i)
    if i % 5 == 4:
        break
print('----------')
for i in a: # 会接着从中间开始用
    print(i)
    if i % 5 == 4:
        break
https://atcoder.jp/contests/abc205/tasks/abc205_b

3 1 2 4 5
2 1 3 4 5
1 2 3 4 5


3 1 4 1 5 2
4 1 3 1 5 2
1 1 3 4 5 2

循环练习题

https://atcoder.jp/contests/abc155/tasks/abc155_b 用 break 和 else

https://atcoder.jp/contests/abc028/tasks/abc028_b
https://atcoder.jp/contests/abc029/tasks/abc029_b
https://atcoder.jp/contests/abc044/tasks/abc044_b
https://atcoder.jp/contests/abc050/tasks/abc050_b
https://atcoder.jp/contests/abc052/tasks/abc052_b
https://atcoder.jp/contests/abc059/tasks/abc059_b
https://atcoder.jp/contests/abc061/tasks/abc061_b
https://atcoder.jp/contests/abc234/tasks/abc064_b
https://atcoder.jp/contests/abc068/tasks/abc068_b
https://atcoder.jp/contests/abc073/tasks/abc073_b

函数和递归

def F(n):
    return 2 * n
print(F(2))

print(None) # 特殊的类型 None

def f():
    return 1, 2 # 返回一个 元组 tuple
    return (1, 2) # 返回一个 元组 tuple
    return [1, 2] # 返回一个 列表 list

x, y = f() # 可以二对二赋值,x和y是变量
# 元组和列表几乎一样,但不能修改

a = f() # a是元组
print(a) # 元组和列表相比,用 ( ) 引起来
print(len(a))
print(min(a))
print(max(a))
print(sum(a))
print(2 in a)
print(4 in a)

print((1, 2) == [1, 2]) # 内容一样的元组和列表不相等

import math
print(math.gcd(6, 8)) # 最大公约数
print(math.lcm(6, 8)) # 最小公倍数 至少 Python 3.9 才可以使用
# lcm(x, y) == x * y / gcd(x, y)
print(6 * 8 // math.gcd(6, 8)) # 最小公倍数

print([1, 2, 3, 4, 5, 6])
print(*[1, 2, 3, 4, 5, 6])
print(' '.join(map(str, [1, 2, 3, 4, 5, 6])))

函数练习题

https://atcoder.jp/contests/abc234/tasks/abc234_a
https://atcoder.jp/contests/abc080/tasks/abc080_b
https://atcoder.jp/contests/abc102/tasks/abc102_a lcm
https://atcoder.jp/contests/abc161/tasks/abc161_a 交换变量

Python 集合

集合没有重复元素
集合是没有顺序的
集合中元素的类型必须是 hashable type,不能是 list set dict

a = set() # 初始化空集
a = {2, 3} # 初始化集合
# 初始化空集不能写 s = {} 这是之后要讲的字典
a.add(1) # 添加元素
print(a)
a.add(1) # 添加元素,set会自动去重
print(a) # 还是1个元素
print(len(a)) # set的大小
print(1 in a) # 判断元素是否在 set 中
a.remove(1) # 从set中删除元素,如果不存在报错
a.discard(1) # 从set中删去元素,如果不存在忽略
a.pop() # 删去并返回任意一个元素
a = set([1, 2, 3, 1, 2, 3]) # 可以直接把列表转为集合
a = set('abcabc') # 可以直接把字符串转为集合
# 集合之前支持 减法,与,或,异或,小于,小于等于 的运算和判断
a = {1, 2}
b = {1, 3}
print(a - b) # 减 差集
print(a & b) # 与 交集
print(a | b) # 或 并集
print(a ^ b) # 异或 对称差
print({1} <= {1, 2}) # 判断子集
print({1} < {1, 2}) # 判断真子集

list的in和set的in效率对比

a = list(range(100000))
b = set(range(100000))
print(len(a))
print(len(b))

s = 0
for i in range(100000):
    if i in b: # 如果使用列表a,就很慢,如果使用集合b,就很快
        s += i
print(s)

集合中不能有list但可以有tuple

s = set()
s.add([1, 1]) # 会报错
s.add((1, 1)) # 不会报错

列表去重的方法

input()
s = input()
ans = ''
for i in s:
    if ans == '' or i != ans[-1]:
        ans += i
print(len(ans))

集合练习题

https://atcoder.jp/contests/abc019/tasks/abc019_3
https://atcoder.jp/contests/abc022/tasks/abc022_b
https://atcoder.jp/contests/abc063/tasks/abc063_b
https://atcoder.jp/contests/abc154/tasks/abc154_c
https://atcoder.jp/contests/abc164/tasks/abc164_c
https://atcoder.jp/contests/abc226/tasks/abc226_b
https://atcoder.jp/contests/abc240/tasks/abc240_b

Python 字典

字典没有重复key (可以有重复的value
字典是没有顺序的
字典中 key 的类型必须是 hashable type 不能是 list set dict
字典中 value 类型任意
很多语言都有类似的内置函数 C++ 的 map Java HashMap/TreeMap
Python dict的缺点是无序的,不能获取最大值和最小值,如果想做这件事的话,需要用 SortedDict

dict 比较简单的用法就是统计出现次数 Counter

a = {} # 初始化空字典
a = {2 : 3} # 初始化字典
a[1] = 0 # 添加或修改元素
print(4 in a) # 判断元素是否存在
print(a[4]) # 不能访问不存在的元素,会出错
print(a.get(4, 233)) # 如果不存在返回默认值,避免出错
del a[1] # 删除元素
a.pop(1) # 删除元素
for i in a: # 枚举所有 key
    print(i, a[i]) # 输出所有 key value

print(list(g)) # 默认就是key
print(list(g.keys()))
print(list(g.values()))

print(max(g.values())) # 求 value 的最大值

z = 0 # 如果所有 value 都小于 0 会出错
for i in g:
    z = max(z, g[i])
print(z)


print(max(g, key=g.get)) # 输出 value 最大的 key


学生 = {}
学生[成绩] = 100
学生[明细] = [第一题, 第二题, 第三题 ……]
学生[明细] = [{得分: 整数, 评价: 字符串}, 第二题, 第三题 ……]

字典练习题

https://atcoder.jp/contests/abc008/tasks/abc008_2
https://atcoder.jp/contests/abc247/tasks/abc247_b
https://atcoder.jp/contests/abc243/tasks/abc243_c
https://atcoder.jp/contests/abc072/tasks/arc082_a
https://atcoder.jp/contests/arc086/tasks/arc086_a
https://atcoder.jp/contests/arc103/tasks/arc103_a
https://atcoder.jp/contests/abc058/tasks/arc071_a
https://atcoder.jp/contests/abc091/tasks/abc091_b
https://atcoder.jp/contests/abc261/tasks/abc261_c
https://codeforces.com/problemset/problem/886/B

文件输入输出

with open('c.in') as fin:
    print(fin.read())
    print(fin.readline())
    print(fin.readlines())

# 读入时 open('c.in', 'r') 可以写作 open('c.in')
with open('c.in', 'r') as fin:
    for line in fin:
        print(repr(line))

# 输出时用 'w' 不能省略
with open('c.out', 'w') as fout:
    print('hello', file=fout)

import sys
sys.stderr
sys.stdout
sys.stdin

package module

内置 module 列表
https://docs.python.org/3/py-modindex.html

import math # 之后需要使用 math.log
from math import * # 之后直接 log 就可以了,不需要 math. 其他函数类似,也不需要 math.
from math import log # 之后直接 log 就可以了,不需要 math. 但是只能使用 math 中的 log 函数


import math, random # 可以同时 import 2个,不推荐这样写


import random

math.log / math.sin / math.cos
random.randint

python3 -m pip install matplotlib
python3 -m pip install numpy 


import datetime

json
datetime
math
random
urllib
re
collections

pip install requests
pandas
numpy

Lambda 匿名函数

a = [1, 2, 3]
print(list(map(lambda x : x * 2, a)))
等价于
def f(x):
    return x * 2
print(list(map(f, a)))

位运算

异或
二进制不进位加法
相同为0,不同为1
0011
0101

0110

((A ^ B) ^ C) == (A ^ (B ^ C))
A + C == B
C = B - A

(A ^ C) == B
C = (B ^ A)

按位与 bitwise and

0011 3
0101 5
&
0001

按位或 bitwise or

0011 3
0101 5
|
0111

左移 shift left
x << y
等价于
x * 2 ** y

3
0011

3 << 2
1100
12

右移 shift right
x >> y
等价于
x // 2 ** y

JSON

希望把数组输出到文件,并且可以方便的从Python中读入
1, 2], [3, 4

1 'asd asd'
3 4

import json
a = [1, [2, 3], 'a', {'b' : 'c'}]
print(json.dumps(a))

urllib / requests

访问网络

距离 欧几里得距离 曼哈顿距离

zip

n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
for i in range(n):
    print(a[i], b[i])
print(a)
print(b)
print(list(zip(a, b)))
print(list(zip(a, b, b, a))) # 可以同时 zip 任意多个数组
for x, y in zip(a, b):
    print(x, y)

列表展开成参数

def f(x, y, z):
    print('x', x)
    print('y', y)
    print('z', z)

a = [4, 5, 6]

f(a[0], a[1], a[2])
f(*a)

a = [4, 5, 6]

# f(a[0], a[1], a[2])
# f(*a)
print(a)
print(*a)
print(' '.join(map(str, a)))

进制转换

乘一项,加一项
7进制456转10进制
((0 * 7 + 4) * 7 + 5) * 7 + 6

模一项,除一项
10进制的 237 转7进制
237 % 7 == 6 <-
237 // 7 == 33
33 % 7 == 5 <-
33 // 7 == 4
4 % 7 == 4 <-
4 // 7 == 0
把每次的余数从下往上连成一起,可以得到结果 456

转二进制

print(bin(123))
print('{:b}'.format(123))

bin函数会加 0b 的前缀

异常处理

try:
<语句>        #运行别的代码
except <名字><语句>        #如果在try部份引发了'name'异常
except <名字><数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生

assert 断言

命名空间和作用域

L(Local):最内层,包含局部变量,比如一个函数/方法内部。
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
G(Global):当前脚本的最外层,比如当前模块的全局变量。
B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

a = 1
def F():
    a = 2
    def G():
        a = 3
        def H():
            nonlocal a
            # global a
            a = 4
            print('H', a)
        H()
        print('G', a)
    G()
    print('F', a)
F()
print('global', a)

OOP

https://en.wikipedia.org/wiki/Duck_typing

https://en.wikipedia.org/wiki/Abstraction_(computer_science)
https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

时间复杂度

abc262_c

https://atcoder.jp/contests/abc262/tasks/abc262_c

题目要求 min(a[i], a[j]) == i and max(a[i], a[j]) == j
分为两种情况
第一种 a[i] == i and a[j] == j and i < j
第二种 a[i] == j and a[j] == i and i < j
对于第一种情况,只需要统计有多少个 x 满足 a[x] == x
在所有满足条件的 x 中选两个作为 i 和 j 就生成了一组答案

对于第二种情况,只需要枚举 i 检查 i < a[i] and a[a[i]] == i
每个满足条件的 i 都可以生成一组答案 (i, j)

  1. Python
    1. 目录
    2. 安装
      1. Python
      2. PyCharm
    3. 基本概念
      1. 使用 Python
      2. 变量 variable
      3. input() 读入一行一个字符串
      4. int 将字符串转换成整数
      5. print 输出
      6. return 返回
      7. 常见运算
      8. 运算赋值
      9. 练习题
      10. 其他题目
      11. 除法取整的妙用
    4. map(int, input().split())
    5. min max
    6. 多对多赋值
    7. Python条件
    8. Python操作符
      1. 练习题
    9. 字符串
      1. 字符
      2. ASCII
      3. 字符串基本操作
      4. 转字符串时 repr 和 str 的区别
      5. 字符
      6. 字符串
      7. 可以用string也可以用int
      8. 复杂的题目
      9. 浮点数
      10. 实数练习题
      11. 难题
      12. sqrt的使用
      13. 简单计数题
      14. 循环 while 和 for in
      15. 阶乘
      16. 取模
      17. Python 2 和 3 的区别
      18. AC Accepted
      19. WA Wrong Answer
      20. RE Runtime Error
      21. TLE Time Limit Exceeded
      22. 循环练习题
      23. 列表
    10. 数组练习题
      1. 循环控制 break continue else
      2. map的实现细节
      3. 循环练习题
      4. 函数和递归
      5. 函数练习题
      6. Python 集合
      7. list的in和set的in效率对比
      8. 集合中不能有list但可以有tuple
      9. 列表去重的方法
      10. 集合练习题
      11. Python 字典
      12. 字典练习题
      13. 文件输入输出
      14. package module
      15. Lambda 匿名函数
      16. 位运算
      17. JSON
      18. urllib / requests
      19. 距离 欧几里得距离 曼哈顿距离
      20. zip
      21. 列表展开成参数
      22. 进制转换
      23. 异常处理
      24. 命名空间和作用域
      25. OOP
      26. 时间复杂度
      27. abc262_c