1 2 bisect_left:>= bisect_right:>
dict 1 2 3 dict = defaultdict(list )dict = defaultdict(inf)
SortedDict 1 dict = defaultdict(SortedDict)
any 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 if any (1 in row for row in grid): return -1 print (any ([0 , False , 5 ])) print (any ([])) print (any ({0 : "False" , 1 : "True" })) print (any ({})) nums = [1 , 4 , 6 , 8 ]print (any (n > 5 for n in nums))
copy 1 2 3 4 5 6 7 8 9 10 11 12 import copy pre_grid = copy.deepcopy(grid) pre_grid = grid pre_grid = grid.copy()
一维数组 1 2 3 4 5 6 7 a_copy = a.copy() a_copy = a[:] a_copy = a
可变对象
可变对象(如列表、字典、集合等)则表现出“按引用传递”的特性。
因为函数接收的参数是对象的引用,所以如果你在函数内部修改了一个可变对象(例如,添加、删除或者修改列表中的元素),
那么这些修改会反映到原始对象上,因为实际上你和函数内部操作的是同一个对象。
不可变对象
不可变对象(如整数、浮点数、字符串、元组 等)看起来像是“按值传递”,因为它们的值不能被修改。
如果你在函数内部试图改变一个不可变对象的值,实际上会创建一个新的对象,并将其绑定到函数内部的局部变量名上,而原始对象不会受到影响。
def 函数参数 在Python中,所有的函数参数 传递都可以视为“按对象引用传递”(pass by object reference)。这意味着函数内部接收到的是实际参数对象的引用,而不是对象的副本。这种传递方式的效果取决于对象本身是可变的(mutable)还是不可变的(immutable)。
不可变 1 2 3 4 5 6 7 8 area = 0 def fun (area ): area += 1 fun(area)print (area)
Python中函数参数如何按引用传递(对于可变对象而言) 1 2 3 4 5 6 area[0 ] = 0 def fun (area ): area[0 ] += 1 fun(area)print (area[0 ])
不可变对象 + global 1 2 3 4 5 6 7 8 area = 0 def fun (): global area area += 1 fun()print (area)
global
使用global
关键字在函数内部声明全局变量 。
当在函数内部修改全局变量时,如果不使用global
关键字,
Python
将会创建一个新的局部变量,而不是修改外部的全局变量。
通过使用global
关键字,可以明确指示Python在函数内部对全局变量进行修改。1 2 3 4 5 6 x = 5 def func (): global x x = 10 func()print (x)
nonlocal
nonlocal
关键字用于在嵌套函数中声明非局部变量(即不属于这个函数,但也不是全局的变量)。
这通常用于在嵌套函数中修改封闭作用域(enclosing scope,即嵌套函数外部的另一个函数内部)的变量。
1 2 3 4 5 6 7 8 9 def outer (): x = 5 def inner (): nonlocal x x = 10 inner() print (x) outer()
使用注意事项 global
和nonlocal
关键主要用于复杂的场景,比如需要在多层嵌套的函数中修改外部变量的值。然而,过度使用这些关键字可能会导致代码难以理解和维护,因此应该谨慎使用。 如果可以通过其他方式(如返回值、类属性等)来实现相同的功能,通常这些方式会更加清晰和优雅。
嵌套函数 在Python中,嵌套函数可以访问其外部函数(父函数)作用域内的所有变量,无论这些变量是可变的还是不可变的。这种特性是由于Python的作用域和闭包的概念所决定的。当你在一个函数内定义另一个函数时,内部的函数(嵌套函数)可以访问外部函数的局部变量。
访问不可变变量 嵌套函数可以读取外部函数中定义的不可变变量(如整数、字符串、元组等),但不能直接修改它们。如果尝试修改,Python会在嵌套函数的局部作用域内创建一个同名的新变量,而不是修改外部函数的变量。这是因为不可变变量不能被更改,只能被替换。
示例:
1 2 3 4 5 6 7 8 Copy codedef outer (): x = 3 def inner (): print (x) inner() outer()
修改可变变量 对于可变变量(如列表、字典等),嵌套函数可以修改这些变量的内容,因为可变变量允许原地修改。
1 2 3 4 5 6 7 8 9 Copy codedef outer (): lst = [1 , 2 , 3 ] def inner (): lst.append(4 ) inner() print (lst) outer()
使用nonlocal关键字 如果需要在嵌套函数中修改外部函数的不可变变量,可以使用nonlocal关键字。这样做可以明确地告诉Python解释器你打算修改的是嵌套作用域中的变量,而不是创建一个新的局部变量。
1 2 3 4 5 6 7 8 9 10 11 python Copy codedef outer (): x = 3 def inner (): nonlocal x x = 5 inner() print (x) outer()
在这个示例中,nonlocal关键字使得inner函数能够修改外部函数outer中定义的不可变变量x的值。 总结来说,嵌套函数能够访问父函数中定义的所有变量,无论它们是可变的还是不可变的。但要修改不可变变量,需要使用nonlocal关键字。
总结 修改不可变复杂一点…… 修改可变,不用加入函数参数直接改!
1 2 3 4 5 6 7 8 my_list = [1 , 2 , 3 ]def modify_list (): my_list.append(4 ) modify_list()print (my_list)
排序 lambda
在python种,lambda
函数后面可以跟一个列表或任何其他类型的表达式。lambda
函数是一个简单的匿名函数,可以接受任何任何数量的参数,但只有一个表达式,这个表达式的就算结果就是函数的返回值。 例如:
排序字典的时候,lambda接受两个参数 item = [k, v]
,然后返回一个参数item[1]
1 sorted_dict_by_value = dict (sorted (my_dict.items(), key=lambda item: item[1 ]))
按值排序索引的时候,接受一个参数,返回一个列表里面两个参数
这里的 lambda 函数对于每个元素 x(在这个上下文中,x 是 lst 中的一个元素,即一个索引)返回一个由两个元素组成的列表:nums[x] 和 x。
这个返回的列表用作排序的键:
第一个元素 nums[x] 是主要的排序依据。
第二个元素 x 作为次要排序依据,确保在 nums[x] 相同的情况下,索引较小的元素排在前面。
1 sort_lst = sorted (lst, key=lambda x: [nums[x], x])
1 2 3 4 5 6 my_dict = {'b' : 1 , 'a' : 2 , 'c' : 3 } sorted_dict = dict (sorted (my_dict.items())) my_dict = {'b' : 1 , 'a' : 2 , 'c' : 3 } sorted_dict_by_value = dict (sorted (my_dict.items(), key=lambda item: item[1 ]))
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 sorted_index = sorted (range (len (nums)), key = nums.__getitem__) sorted_index = [i for i, _ in sorted (enumerate (nums), key=lambda x: x[1 ])] nums_index = [[num, i] for i, num in enumerate (nums)] sorted_index = [i for num, i in sorted (nums_index, key = lambda x : x[0 ])] n = len (nums) lst = list (range (n)) lst.sort(key=lambda x: [-nums[x], -x]) n = len (nums) lst = list (range (n)) sort_lst = sorted (lst, key = lambda x: nums[x]) sort_lst = sorted (lst, key = lambda x: [nums[x], x])
sort_lst = sorted(lst, key=lambda x: nums[x]):
这个表达式根据 nums
中每个索引 x 对应的值对 lst
进行排序。如果 nums 中存在相同的值,那么它们对应的索引在 sort_lst
中的相对顺序将按照它们在原列表 lst
中的顺序,也就是说,排序是稳定的。
sort_lst = sorted(lst, key=lambda x: [nums[x], x]):
这个表达式在排序时考虑了两个因素:首先是 nums 中每个索引 x 对应的值,其次是索引 x
本身。这意味着,如果 nums
中有两个或多个相同的值,它们将进一步按照它们的索引进行排序。这种方法确保了即使在 nums
中的值相等时,排序结果也是确定的,因为索引值是唯一的。
accumulate 内置前缀和
1 2 3 4 5 6 7 8 9 10 11 import itertools import operator data = [1 , 2 , 3 , 4 , 5 ]print (list (itertools.accumulate(data)))print (list (accumulate(data))) data = [3 , 4 , 6 , 2 , 1 , 9 , 0 , 7 , 5 , 8 ]print (list (itertools.accumulate(data, operator.mul, initial=2 )))print (list (itertools.accumulate(data, max )))
enumerate 在Python中,enumerate 是一个内置函数,用于将一个可迭代的(比如列表、元组、字符串等)组合成一个索引序列,通常用于在for循环中获取每个元素的索引和值。这样可以在遍历时同时获得每个元素的索引位置和对应的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for index, value in enumerate (iterable, start=0 ): print (index, value) my_list = ['apple' , 'banana' , 'cherry' ]for index, value in enumerate (my_list): print (f"Index: {index} , Value: {value} " ) Index: 0 , Value: apple Index: 1 , Value: banana Index: 2 , Value: cherry
使用 enumerate 可以使代码更加清晰和简洁,特别是当你需要索引和值时。
图论 邻接表 1 2 3 4 5 6 7 8 g = defaultdict(list )while x, y in deges: g[x].append(y) g[y].adppen(x)while x, y, d in deges(): g[x].append((y, d)) g[y].append((x, d))
并查集 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 35 36 37 p = list (range (n))def find (x ): if x != p[x]: p[x] = find(p[x]) return p[x]def merge (x, y ): px = find(x) py = find(y) if px != py: p[px] = p[py] p = list (range (n)) size = [1 ] * n num_components = n def find (x ): if x != p[x]: p[x] = find(p[x]) return p[x]def merge (x, y ): px = find(x) py = find(y) if px != py: global num_components if size[px] < size[py]: p[px] = py size[py] += size[px] else : p[py] = px size[px] += size[py] num_components -= 1
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 35 36 37 38 39 40 41 42 43 44 45 46 class UnionFind : def __init__ (self, n ): self.root = [i for i in range (n)] self.size = [1 ]*n self.part = n def find (self, x ): if x != self.root[x]: root_x = self.find(self.root[x]) self.root[x] = root_x return root_x return x def union (self, x, y ): root_x = self.find(x) root_y = self.find(y) if root_x == root_y: return if self.size[root_x] >= self.size[root_y]: root_x, root_y = root_y, root_x self.root[root_x] = root_y self.size[root_y] += self.size[root_x] self.size[root_x] = 0 self.part -= 1 return def is_connected (self, x, y ): return self.find(x) == self.find(y) def get_root_part (self ): part = defaultdict(list ) n = len (self.root) for i in range (n): part[self.find(i)].append(i) return part def get_root_size (self ): size = defaultdict(int ) n = len (self.root) for i in range (n): size[self.find(i)] = self.size[self.find(i)] return size
数论 1 2 3 4 5 6 7 8 9 10 def quick_pow (a, b, mod ): res = 1 while b: if b & 1 : res = res * a % mod a = a * a % mod b >>= 1 return resdef inverse (a, mod ): return quick_pow(a, mod - 2 , mod)
1 2 def gcd (a, b ): return a if b == 0 else gcd(b, a % b)
1 2 3 4 5 6 7 8 9 10 def sieve (n ): primes = [] st = [0 ] * (n + 1 ) for i in range (2 , n + 1 ): if not st[i]: primes.append(i) for j in range (i * i, n + 1 , i): st[j] = 1 return primes
1 2 3 4 5 6 7 8 9 def is_prime (n ): if n < 2 : return False i = 2 while i <=n // i: if n % i == 0 : return False i += 1 return True
用Python编码更简单:
1 2 3 4 5 6 7 n = int(input()) s = 1 ans = 0 for i in range(1,n+1,1): s *= i ans += s print(ans)
C.2 构造随机数和随机字符串 用Python构造测试数据,比c++简单得多。它能直接产生极大的数字,方便地产生随机字符等。下 (1)导入库
可以写成:
此时后面的代码能够简单一点,例如把random.randint
直接写为randint
(2)在指定范围内生成一个很大的随机整数:
1 print (random.randint(-9999999999999999 ,9999999999999999 ))
输出示例:428893995939258 (3)在指定范围内(0到100000)生成一个随机偶数:
1 print (random.randrange(0 , 100001 , 2 ))
输出示例:14908 (4)生成一个0到1之间的随机浮点数:
输出示例:0.2856636141181378 (5)在指定范围内(1到20)生成一个随机浮点数:
1 print (random.uniform(1 , 20 ))
输出示例:9.81984258258233 (6)在指定字符中生成一个随机字符:
1 print (random.choice('abcdefghijklmnopqrst@#$%^&*()' ))
输出示例:d (7)在指定字符中生成指定数量的随机字符:
1 print (random.sample('zyxwvutsrqponmlkjihgfedcba' ,5 ))
输出示例:[‘z’, ‘u’, ‘x’, ‘w’, ‘j’] (8)导入库
若写成from string import *
,下面的string.ascii_letters
改为ascii_letters
(9)用a-z、A-Z、0-9生成指定数量的随机字符串:
1 2 ran_str = '' .join(random.sample(string.ascii_letters + string.digits, 8 ))print (ran_str)
输出示例:iCTm6yxN (10)从多个字符中选取指定数量的字符组成新字符串:
1 print ('' .join(random.sample(['m' ,'l' ,'k' ,'j' ,'i' ,'h' ,'g' ,'d' ], 5 )))
输出示例:mjlhd (11)打乱数组的顺序:
1 2 3 4 items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] random.shuffle(items) for i in range(0,len(items),1): #逐个打印 print (items[i]," ",end='')
输出示例:1 0 8 3 5 7 9 4 6 2
对拍 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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 import osfrom random import randint, uniformimport subprocess T = 10 def generate_date (): A = [0 ] * 1010 for t in range (1 , T + 1 ): filename = f"in_{t} .txt" with open (filename, "w" ) as file: n = randint(1 , 1000 ) k = randint(1 , n) file.write(str (n)+ " " + str (k) + "\n" ) for i in range (n): A[i] = randint(0 , 100 ) nums = " " .join(map (str , A[:n])) file.write(nums + "\n" ) print (f'generate_ok:......{T} ' )def run (process_name ): for t in range (1 , T + 1 ): out_filename = f"{process_name} _out_{t} .txt" in_filename = f"in_{t} .txt" subprocess.run(['python' , f'{process_name} .py' ], stdin = open (in_filename, "r" ), stdout = open (out_filename, "w" )) print (f'run_{process_name} _ok:......{T} ' )def diff (file1, file2 ): for t in range (1 , T + 1 ): f1 = f"{file1} _out_{t} .txt" f2 = f"{file2} _out_{t} .txt" with open (f1, "r" ) as s, open (f2, "r" ) as ss: lines1 = s.readlines() lines2 = ss.readlines() if len (lines1) != len (lines2): print (f'{t} :lines error' ) continue ok = 1 for line1,line2 in zip (lines1, lines2): if line1 != line2: print (f'{t} :exist error' ) ok = 0 break if ok: print (f'{t} :ok' )if __name__ == "__main__" : generate_date() file_true = "True" run(file_true) file_my = "A" run(file_my) diff(file_true, file_my)