python 的语法笔记

使用python 实现字典与列表的嵌套

类似于C++中

1
2
vector<vector<int>>h1;
unordered_map<int,vector<int>>h2;

python 虽然不能像C++ 这样实现无限套娃 也基本足够 即可可实现 int:list 即一个整数 或 字符/字符串 对应的列表 在建图的时候 会非常方便 但在构造题中还是直接上C++ 的 unordered_map 会舒服一些

1
2
3
4
5
6
7
8
"""
这个是需要引入的 如果是写一些oj 或者 kickstart 就要注意一下
但在leetcode中 整个collections 集合都是 自动帮我们引入好的直接 而且还是这种 from import的形式 所以直接用defaultdict就OK了
"""
from collections import defaultdict
h = defaultdict(list)
h[0].append(0)
h[1].append(0)

python {} 可能是默认为 set 也可能是 dict

python {} 可能是默认为 set 也可能是 dict 写的时候一定要明确明set 还是dict 尽量不要直接用这种形式

1
2
3
4
5
# 不要使用
t = {}
# 尽量以下 几种方式初始化
s = set()
d = dict()

python的遍历

python的 遍历 没有C++ 那么自由 但却提供了很多接口 方便了很多

enumerate 同时获取下标和值

使用 enumerate 可以同时获取下标和值 否则要用range迭代的方式获取 比较繁琐

1
2
3
4
5
6
7
q = [3,2,1]
"""
遍历enumerate时
第一个参数为 下标 第二个参数为 值
"""
for index,val in enumerate(q):
print(index,val)

zip 同时遍历多个集合

zip 相当于把多个集合打包 然后相对的去遍历即可

1
2
3
4
5
a = [1,2,3]
b = [2,3,4]
for i,j in zip(a,b):
print(i,j)

还可以将 zip 和 enumerate 套娃使用

1
2
3
4
5
a = [1,2,3]
b = [2,3,4]

for (i,v),(j,w) in zip(enumerate(a),enumerate(b)):
print(i,v," ",j,w)

python 切片

python切片 q[l:r] 这个范围range是一样的 右边取不到的 所以要取 l:r 范围的数 那实际上应该是 q[l:r+1]
可以玩的操作很多 比如直接 用sum就可以获取这一段区间的值
通常会用作滑动窗口 这样就不用写双指针了 代码正确率大大提升

切片旋转

这个非常使用 再有些题目中 甚至如果逆序的时候不想写reverse 也可以全局切片翻转

1
2
3
4
5
6
# 两元素交换 如果a,b挨着那用切片也可以做
q[a],q[b] = q[b],q[a]

# 整段元素翻转
# 翻转 a,b 区间的元素
q[a:b+1][::-1]

python 的输入输出

在一些oj题中会用到 会以后kickstart做准备
没有 C++ 那么 自由 但比java 要好很多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"""
输入样例:
2
5 5
...**
*.**.
.....
.....
*....
"""
T = int(input())
m,n = map(int,input().split())
print(T,m,n)
g = [["" for i in range(n)] for j in range(m)]
for i in range(n):
g[i] = input()
print(g[i])

主要需要注意的是 字符间有字符隔开的情况 需要用到map 去做一个对应 另外 二维字符数组的初始化通常也要这样写会比较好
总之python 的输入 都是按行 任何对字符的操作按行进行分割对应即可

字典的遍历和初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from collections import Counter, defaultdict

"""
想要实现和C++ unordered_map 那样自动插入的效果就一定要用defaultdict()
其他如list deque 也建议都用default 这个函数 (collections中基本可以视为基本库 只管用就完事了)
"""
d = defaultdict(int)
d[1]=8
d[3] = 2
d[2] = 7

# 遍历每一个键值对
# 这里要注意 python的遍历顺序只会按照你的添加顺序遍历 而并非键值顺序
for (i,j) in d.items():
print(i,j)

# 遍历 key
for k in d.keys():
print("k = {}".format(k))

# 遍历value
for v in d.values():
print("v = {}".format(v))

# 按键值顺序遍历
"""
如果直接sorted(d) 或者 直接 for i in d 那么默认操作和排序的都是键值 这个和C++ 很不一样的
"""
# 排序键值对
di = sorted(d.items())
# 排序键值
dk = sorted(d.keys())
# 排序值
dv = sorted(d.values())

python 字典自定义排序

通过这种自定义排序方法 基本就可以弥补python 没有红黑树的遗憾了

1
2
3
4
5
6
7
8
9
10
11
from collections import defaultdict

d = defaultdict(int)
d[0] = 3
d[1] = 0
d[2] = 1

# 按照 value 的值对字典进行排序 返回是元素为元组的列表
# 这里注意想要对字典整体进行排序 就直接排items() 就可以了 这里定义排序规则时 把items() 理解为一个有二维的list即可
ds = sorted(d.items(), key=lambda x: x[1])
print(ds)

python 二分库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from bisect import bisect_left, bisect_right

a = [2, 4, 5, 5, 5, 9]
x = 3
"""
一下讨论均基于 数组a 有序的前提下
当要查找的数x 在数组a中不存在相同的多个 两者是没有区别的
都会返回使得插入元素到数组a 后 使得数组有序的 那个下标索引
"""
print(bisect_left(a, x), bisect_right(a, x))

x = 5
"""
当要查找的数存在相同多个时
bisect_left 返回相同数 下标中最靠左的那个
bisect_left 返回相同数 下标中最靠右的那个
"""
print(bisect_left(a, x), bisect_right(a, x))