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)
,这样执行效率高
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
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的幂
官方文档: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会返回True,如果iterable对象中的元素有一个为True
all会返回True,当iterable对象中的所有元素为True
注:0认为是False
官方文档:https://docs.python.org/zh-cn/3/library/collections.html
双向的list,在普通list外另有appendleft, popleft
普通的list,append
(向尾部插入元素)和pop
(删除尾部元素)时间复杂度都是o(1)
,但是对头部元素的操作是o(n)
,deque可以保证头部元素的操作时间复杂度也是o(1)
官方文档:https://docs.python.org/zh-cn/3/library/heapq.html
如果想建大根堆,则排序的key取负数即可
堆的操作可以在所有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)
官方文档:https://docs.python.org/3/library/bisect.html
常用的是:
bisect.bisect_left(a, x, lo=0, hi=len(a))
,意义是返回将x
插入a[lo:hi]
时的最左边索引
bisect.bisect_right(a, x, lo=0, hi=len(a))
是最右边索引
二分查找可以写成:
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
官方文档: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')]
官方文档: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')]