Python基础运用
1. 位运算符
1.1 移位运算符 <<、 >>
- 左乘右除
m << n
二进制数左移n位,高位扩增,低位补0
相当于m乘 2的n次方m >> n
二进制数右移n位,高位缩减,低位丢弃
相当于m除2的n次方
1.2 按位逻辑运算
m & n
按位与运算,如:3 & 2 >>> 2 (11 & 10 >>> 10)
m | n
按位或运算,如:3 | 2 >>> 3 (11 | 10 >>> 11)
m ^ n
按位异或运算,不同为1相同为0,如:3 ^ 2 >>> 1 (11 | 10 >>> 01)
2. list, set, dict 操作和时间复杂度
2.1 list
2.1.1 常用操作
- 列表中元素可重复
list.append(i)
添加元素i,加入后插入末尾list.remove(i)
取出元素i不返回,没有i时报错,[1, 2, 1]移除1时优先移走前面的1n = list.pop()
取出最后一个元素并返回n = list.pop(idx)
取出索引为idx的元素,并返回list.insert(idx, num)
在索引idx处插入元素num,原索引[idx: ]后移list.sort()
排序 【Python】排序 - sort()/sorted()print(*list)
获取list里的元素,用空格间隔
2.1.2 [[]] * n & [[] for _ in range(n)]
'''
[[]] * 3 >>> [[], [], []]
三个列表指向同一个地址,一个列表.append()添加元素,其余列表也会添加
'''
l = [[]] * 3
l[0].append(1)
l
'''
[[1], [1], [1]]
'''
'''
[[] for _ in range(3)] >>> [[], [], []]
三个列表指向不同地址,.append()互不干扰
'''
l = [[] for _ in range(3)]
l[0].append(1)
l
'''
[[1], [], []]
'''
2.1.3 [0] * 3 & [0 for _ in range(3)]
'''
[0] * 3 >>> [0, 0, 0]
三个常量指向相同地址,实际为一个常量,即列表装了三个相同的地址
l[0] = 1,将地址替换为另一个地址 >>> [1, 0, 0]
'''
l = [0] * 3
for i in range(3):
print(id(l[i]))
'''
140715125384976
140715125384976
140715125384976
'''
l[0] = 1
'''
[1, 0, 0]
'''
'''
[0 for _ in range(3)] >>> [0, 0, 0]
居然和上面[0] * 3一样了,三个数都是同一个地址,奇怪
如果是列表作为元素的话,会是三个不同的列表
'''
l = [0 for _ in range(3)]
for i in range(3):
print(id(l[i]))
'''
140715125384976
140715125384976
140715125384976
'''
2.1.4 list 列变行
n x 60 >>> 60 x n
l = [[1, 2, 3, 4], [1, 2, 3, 4]]
'''
*l 把l中的一个个list取出来
zip(*l) 一个个list进行打包,每次迭代输出不同list中相同索引的元素,
-> (l1[0], l2[0],...), (l1[1], l2[1], ...)
list(zip(*l))
-> [(l1[0], l2[0],...), (l1[1], l2[1], ...)]
list(map(list, list(zip(*l))))
-> [[l1[0], l2[0],...], [l1[1], l2[1], ...]]
'''
list(map(list, list(zip(*l))))
2.1.5 list 拼接 、二维list转为一维
- list1 + list2 相加等价于拼接,返回的是新建对象;
[1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6] list1.extend(list2)
在list1对象的基础上添加元素,不新建元素,无返回值;- sum(list2d, []) 铺平list2d :
'''
l 中的[1, 2, 3]与[4, 5]相加 >>> [1, 2, 3, 4, 5]
[1, 2, 3, ,4, 5] + [] >>> [1, 2, 3, 4, 5]
若是不放空list [], sum默认与0相加,报错。
'''
l = [[1, 2, 3], [4, 5]]
sum(l, [])
'''
[1, 2, 3, 4, 5]
'''
2.2 set
2.2.1 常用操作
- 集合中元素不重复,加入重复元素只保留一个元素
set.add(i)
添加元素i,加入后是排序的set.remove(i)
取出元素i不返回,没有i时会报错set.discard(i)
取出元素i不返回,没有i时不报错n = set.pop()
取出第一个元素并返回set.update(list)
添加列表的元素到集合set.clear()
移除所有元素
set 底层实现方式是哈希表,查找元素的时间复杂度为O(1)
2.2.2 并集 set1.union/update(set2) |
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set1.union(set2) # set1.update(set2)
'''
{1, 2, 3, 4, 5}
'''
set1 | set2
'''
{1, 2, 3, 4, 5, 6}
'''
2.2.3 交集 set1.intersection(set2) &
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set1.intersection(set2)
'''
{3}
'''
set1 & set2
'''
{3}
'''
2.2.4 差集 set1.difference(set2) -
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set1.difference(set2)
'''
{1, 2}
'''
set1 - set2
'''
{1, 2}
'''
2.3 dict
2.3.1 常用操作
dict.pop(key)
删除key的键值对,并返回valuedel dict[key]
删除key的键值对,不返回dict[key] = value
添加键值对 or 重新赋值键值对dict.update(dict)
添加/更新集合的元素到集合
dict 底层实现方式是哈希表,查找元素的时间复杂度为O(1)
除了dict.copy()和循环迭代的时间复杂度O(n),其余都为O(1)
2.3.2 合并两个dict
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
d1.update(d2)
d1
'''
{'a': 1, 'b': 3, 'c': 4}
'''
** 字典解包操作符
注意前后更新顺序
d3 = {**d1, **d2}
'''
{'a': 1, 'b': 3, 'c': 4}
'''
d3 = {**d2, **d1}
'''
{'b': 2, 'c': 4, 'a': 1}
'''
2.3.3 指定两list为Key和Value,转为dict dict(zip(l1, l2))
l1 = ['a', 'b', 'c']
l2 = [1, 2, 3]
dict(zip(l1, l2))
'''
{'a': 1, 'b': 2, 'c': 3}
'''
3. reduce 对可迭代对象元素的累积操作
-
reduce(func, iterable[])
func
函数iterable
可迭代对象
-
对参数序列中元素进行累积
# python3
from functools import reduce
def add(x, y) : # 两数相加
return x + y
sum1 = reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5
sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
4. Python 读数据
4.1 python 3.x input()
- 读入的格式皆为字符串,需要类型转换;
- 一次
input()
读取一行,读取的是字符串;
n = int(input())
q = [0] * n
for i in range(n):
q[i] = int(input())
'''
输入:
3
1
2
3
'''
- 若一行中包含多个数字,使用
split()
方法将输入的字符串拆分为多个子字符串,
并使用map()
函数将这些子字符串转换为整数,最终将它们存储在 q 列表中。
n = int(input())
q = list(map(int, input().split()))
'''
输入:
3
1 2 3
'''
4.2 python 2 row_input()
- 在 Python 2.x 版本中,
input()
函数会把输入的内容当做 Python 代码进行解析,而不是简单地将其作为字符串处理。 - 将
input()
函数替换为raw_input()
函数,raw_input()
函数会把输入的内容作为字符串处理,而不会将其解析为 Python 代码。
4.3 sys.stdin.readline() 速度更快
- 列表元素少的话可以尝试单独用
int(nums[i])
转换类型
import sys
n = int(sys.stdin.readline())
nums = list(map(int, sys.stdin.readline().split()))
print(n, type(n))
print(nums, type(nums[0]))
'''
2 <class 'int'>
[3, 2, 5] <class 'int'>
'''
5. 类的继承 super.__init __()
- 要用父类的参数的时候,要
super().__init__()
初始化父类 - 不用父类的参数的时候,可以不用初始化父类
【Pytorch】torch.nn.module
class MyParentClass:
def __init__(self, x):
self.x = x
class MyChildClass(MyParentClass):
def __init__(self, x, y):
super().__init__(x)
self.y = y
obj = MyChildClass(1, 2)
print(obj.x) # Output: 1
print(obj.y) # Output: 2
-
torch.utils.data.Dataset
类不含有init
构造函数,所以子类的构造函数中不需要初始化父类。 -
Python 3 中,可以直接使用
super()
函数来调用父类方法,而不需要传递参数。例如,可以使用super().__init__()
来调用父类的构造函数。 -
Python 2 中,需要显式地传递两个参数,即
super(子类名, self)
。子类名 是当前子类的名称,self 是当前子类实例的引用。
6. 字符 - ASCII码值
6.1 ord() 获取一个字符的ASCII码值
- C++中可以直接计算字符的ASCII码值。
'c' - 'a' >>> 2
- Python 需要使用内置函数
ord()
进行转换ord('c') - ord('a') >>> 2
6.2 chr() ASCII码值转换为对应字符
- 只接受0到255范围内的整数作为参数
chr(123) >>> '{'
7. 优先队列 queue.PriorityQueue
from queue import PriorityQueue
- 一次插入多个值时,优先比较第一个值
PriorityQueue().put((1, 'a'))
在1相同时比较‘a’ .get()
取出优先级最高的元素
from queue import PriorityQueue
q = PriorityQueue()
'''
第一个值相同时,比较第二个值“task1/2/3”
'''
q.put((5, "task1")) # 优先级为 5 的任务 "task1"
q.put((3, "task2")) # 优先级为 3 的任务 "task2"
q.put((7, "task3")) # 优先级为 7 的任务 "task3"
# 检查队列是否为空
print(q.empty()) # False
# 从队列中取出优先级最高的元素
print(q.get()) # (7, "task3")
8. 双端队列 collections.deque
- 不指定大小(maxlen)时,无限大小;
- 从右端添加、删除元素
.append()
.pop()
; - 从左端添加、删除元素
.appendleft()
.popleft()
; - 固定大小
deque(maxlen=)
,当队列已满再加入元素时,队列最左端元素被剔除
from collections import deque
q = deque(maxlen=3)
q.append(1)
q.appendleft(2)
q.append(3)
q
'''
deque([2, 1, 3], maxlen=3)
'''
q.append(4)
q
'''
deque([1, 3, 4], maxlen=3)
'''
9. 符号作用区分
9.1 = & .copy()
'''
a 和 b指向同一地址,一个改变另一个的读取也改变。
'''
a = [1, 2]
b = a
'''
a 和 c 两个独立的地址
'''
c = a.copy()
9.2 == & is
- 内存空间地址一样则值一定一样;值一样内存空间地址不一定一样。
- 比较两个对象的值是否一样
a == b
- 比较两个的内存空间地址是否一样
a is b
10. python和C++取余运算
- 数学上 取余运算结果大于等于0
- C++
-8 % 5 >>> -3
8 % 5 >>> 3
5的正负不影响结果
- python
8 / 5 >>> 1.6
8 // 5 >> 1
8 % 5 >>> 3
math.fmod(-8, 5) >>> -3.0
-8 % 5 >>> 2 ???
11. 可变数量传参 *args **argss
'''
*args 可变数量的位置参数,以元组的方式收集
**argss 可变数量的关键字参数,以字典的方式收集
'''
def fun(a, b, c=1, *args, **argss):
print(f'a={a} b={b} c={c}')
print(f'*args: {args} {type(args)}')
print(f'**argss: {argss} {type(argss)}')
fun(1, 2, 3, 4, 5, f=6, g=7)
'''
a=1 b=2 c=3
*args: (4, 5) <class 'tuple'>
**argss: {'f': 6, 'g': 7} <class 'dict'>
'''