文章目录
list/tuple
list转置
x
[[1, 2, 3, 4], [1, 2, 3, 4]]
y = list(zip(*x))
y
[(1, 1), (2, 2), (3, 3), (4, 4)]
注意,转置后的矩阵,列表中的元素为tuple
比较
按照顺序,从前向后依次比较每个元素。当所有比较的元素都相同时,短的那个小
x = [1,2,3,4]
y = [1,2,3,4,5]
x > y
False
x = [[1,2,3,4]]
y = [1,2,3,4,5]
x > y
TypeError: '>' not supported between instances of 'list' and 'int'
字符串
字符串拼接
在loop中不要用a += new_str
,最好用list相加,最后再''.join(a_list)
,这样执行效率高
数学
10的几次方
1e1
表示10的1次方,1e6
表示
1
0
6
10^6
106,注意结果是个float
除法向上取整
用//
是向下取整,有时候需要向上取整,即 希望能有:10 / 3 = 4
方法:(a + (b - 1)) // b
注意点:不适合负数
判断奇数/偶数
奇数:x & 1
为1
偶数:x & 1
为0
原因:奇数的最后1位为1,所以相与就还是1。偶数最后1位是0,相与之后就是0
只保留最右边的1,其他位全为0
x & (-x)
去掉最右边的1,保留其他位
x & (x - 1)
判断x是否为2的幂
x and (not (x & (x - 1)))
假设x是2的幂,如8,则满足:只有最高位是1,剩下的位都是0,此时x & (x - 1)
应该是全0的,取个not
,则变成逻辑值True
为了避免x
本身是0造成的例外,前面再加个x and True
,如果x = 0
,则x and True = False
,否则x and True = True
,即x是2的幂
Common prefix for 2 binaries
Move 2 binary numbers to right at the same time, keep track of how many times we moved. When they are equal to each other, they are one part of the common prefix, move the part to left the same time to pad 0s to get the common prefix.
内置函数
zip
官方文档:https://docs.python.org/3/library/functions.html#zip
对于输入的iterable对象,每个对象取1个iter元素,直到最短的iterable对象结束
zip(*iterables)
# zip('ABCD', 'xy') --> Ax By
# zip可以很方便地转置二维数组
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
list(zip(*a))
>> [(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]
# 这里的*a,是取了iterable对象a中的元素,也即4个1维数组,再对4个1维数组做zip
any, all
any会返回True,如果iterable对象中的元素有一个为True
all会返回True,当iterable对象中的所有元素为True
注:0认为是False
内置数据结构
collections.deque
官方文档:https://docs.python.org/zh-cn/3/library/collections.html
双向的list,在普通list外另有appendleft, popleft
普通的list,append
(向尾部插入元素)和pop
(删除尾部元素)时间复杂度都是o(1)
,但是对头部元素的操作是o(n)
,deque可以保证头部元素的操作时间复杂度也是o(1)
heapq/小根堆
官方文档:https://docs.python.org/zh-cn/3/library/heapq.html
如果想建大根堆,则排序的key取负数即可
堆顶元素始终位于heap[0]
堆的操作可以在所有iterable对象上进行,这里以list为例:
b = [1,6,8,4,2,1,8]
import heapq
# 建堆
heapq.heapify(b)
# 此时b的内部已经是堆了
print(b)
>> [1, 2, 1, 4, 6, 8, 8]
# 或者更常用的:
b = []
for item in iterable:
heapq.heappush(b, item)
# 此时b是列表,后续的操作用heapq.heappush, heapq.heappop操作即可
# 建堆时,也可以使用元组,只要保证元组的第一个元素是sort_key即可,详见官方文档
# push
heapq.heappush(b, 5)
>> [1, 2, 1, 4, 6, 8, 8, 5]
# pop,弹出最小的元素
heapq.heappop(b)
>> 1
print(b)
>> [1, 2, 5, 4, 6, 8, 8]
# 先push一个元素,再pop出最小的元素, 比手动heappush(), 再heappop()要快一些
heapq.heappushpop(b, 7)
>> 1
print(b)
>> [2, 4, 5, 7, 6, 8, 8]
# 先pop最小的元素,再push元素,比手动heappop(),再heappush()快
heapq.heapreplace(b, 10)
>> 2
print(b)
>> [4, 6, 5, 7, 10, 8, 8]
# 返回前n个最大的数
heapq.nlargest(4, b)
>> [10, 8, 8, 7]
# 返回前n个最小的数
heapq.nsmallest(4, b)
>> [4, 5, 6, 7]
# 合并有序数组
heapq.merge(*iterables, key=None, reverse=False)
Build a max-heap of strings
Use a self defined class like below:
class MaxHeapObj(str):
def __init__(self, string):
self.string = string
def __lt__(self, other):
return self.string > other.string
def __eq__(self, other):
return self.string == other.string
MaxHeapObj
is a sub-class of str
, and we changed the rule of <
.
bisect
官方文档:https://docs.python.org/3/library/bisect.html
常用的是:
bisect.bisect_left(a, x, lo=0, hi=len(a))
,return i
that a[:i] < x
bisect.bisect_right(a, x, lo=0, hi=len(a))
, return i
that a[:i] <= x
二分查找可以写成:
import bisect
# 找到target的第一个下标,如果不存在则返回-1
def find_first_index(nums: list, target: int) -> int:
loc = bisect.bisect_left(nums, target)
if loc != len(nums) and nums[loc] == target:
return loc
return -1
# 找到target的最后一个下标,如果不存在则返回-1
def find_last_index(nums: list, target: int) -> int:
loc = bisect.bisect_right(nums, target)
if nums[loc - 1] == target:
return loc - 1
return -1
# 找到比target小的最大值,如果不存在返回-1
def find_smaller_greatest(nums: list, target: int) -> int:
loc = bisect.bisect_left(nums, target)
if loc:
return nums[loc - 1]
return -1
itertools.permutations
官方文档:https://docs.python.org/zh-cn/3/library/itertools.html
import itertools
list(itertools.permutations('abcd', 2))
# out:
[('a', 'b'),
('a', 'c'),
('a', 'd'),
('b', 'a'),
('b', 'c'),
('b', 'd'),
('c', 'a'),
('c', 'b'),
('c', 'd'),
('d', 'a'),
('d', 'b'),
('d', 'c')]
itertools.combinations
官方文档:https://docs.python.org/zh-cn/3/library/itertools.html
import itertools
list(itertools.combinations('abcd', 2))
# out:
[('a', 'b'),
('a', 'c'),
('a', 'd'),
('b', 'c'),
('b', 'd'),
('c', 'd')]