python知识点笔记

python知识点笔记


记录一些python上遇到的知识点方便日后查询。

1. lambda

lambda本质上是一个写在一行中的函数, 冒号左侧为函数输入值,右侧为返回值,可以有多个输入和返回。

lambda x:x+1

lambda x, y:x+y

2. map()

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,相当于对后续输入的可迭代对象中的每一个元素做函数的操作。
返回一个map迭代器,可使用list()或set()转换为list和set对象进行查看。
map(function, iterable, …)

list(map(lambda x:x+1, [1, 2, 3]))

list(map(lambda x, y:x+y, [1, 2, 3], [4, 5, 6]))

3. 获取当前代码文件所在路径

current_path = os.path.split(os.path.realpath(__file__))[0]

4. 使用*解包和使用zip()打包

当输入是一个未定长度的列表,而函数输入要求所有变量分别输入时,使用*将列表中的每个元素单独展开作为变量输入。
在numpy库的部分函数中,有时候需要使用这种方式输入。

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。

# 使用python一行完成矩阵旋转
# 转自https://leetcode-cn.com/problems/rotate-image/comments/712701

nums = [[1,2,3],[4,5,6],[7,8,9]]
# 使用*反序解包
print(*nums[::-1])
# [7, 8, 9] [4, 5, 6] [1, 2, 3]

# 使用zip将元素挨个打包
nums[:] = zip(*nums[::-1])
print(nums)
# [(7, 4, 1), (8, 5, 2), (9, 6, 3)]

5. reduce() 函数

会对参数序列中元素进行累积。

函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
例:对列表中的每个数字进行求和

from functools import reduce

def get_sum(nums):
    return reduce(lambda x, y: x + y, nums)		
	
print(get_sum([1,3,5,6]))

6. 位运算符

& 按位与运算符
| 按位或运算符
^ 按位异或运算符:当两对应的二进位相异时,结果为1
~ 按位取反运算符
<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。
同:>> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数

例:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。使用异或运算得到结果。

def singleNumber(nums):
	return reduce(lambda x, y: x ^ y, nums)

7. 使用[:]在函数不返回的情况下对列表本身的值进行改变

def merge(a, b):
		a = a + b
		
a = [1, 2, 3]
b = [4, 5, 6]

merge(a, b)
print(a)

[1, 2, 3]

def merge(a, b):
		a[:] = a + b
		
a = [1, 2, 3]
b = [4, 5, 6]

merge(a, b)
print(a)

[1, 2, 3, 4, 5, 6]

8. 查询列表中第一个指定元素的索引

# 查询第一个指定元素的位置
index = list_1.index(element)

9. 正则表达式

识别字符串开头的数字,代码与说明转自leetcode

def myAtoi(self, s):
        return int(*re.findall('^[\+\-]?\d+', s.lstrip()))

作者:QQqun902025048
链接:https://leetcode-cn.com/problems/string-to-integer-atoi/solution/python-1xing-zheng-ze-biao-da-shi-by-knifezhu/
来源:力扣(LeetCode)

^:匹配字符串开头
[\+\-]:代表一个+字符或-字符
?:前面一个字符可有可无
\d:一个数字
+:前面一个字符的一个或多个
\D:一个非数字字符
*:前面一个字符的0个或多个

10. enumerate() 函数

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标。

seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print(list(enumerate(seasons)))

[(0, ‘Spring’), (1, ‘Summer’), (2, ‘Fall’), (3, ‘Winter’)]

11. 堆heapq

# 导入库
from heapq import * 

# 用一个列表充当堆
heap = [] 

# 加入元素
for i in range(10):
	heappush(heap, i)
	
# 取出最小元素
min_val = heappop(heap)

# 将普通列表整理为一个最小堆
list1 = [4, 3, 1, 2, 7]
heapify(list1)
# list1 = [1, 2, 4, 3, 7]

# 将所有数字取负输入,再取负输出,即可将其作为最大堆使用。
list2 = list(map(lambda x:-x,[4, 3, 1, 2, 7]))
heapify(list2)
# list2 = [-7, -4, -1, -2, -3]

# 也可以按照元素的顺序进行对第一个元素的排序
list3 = [(4,1), (3,9), (1,4), (2,3), (7,2)]
heapify(list3)
print(list3)
# list3 = [(1, 4), (2, 3), (4, 1), (3, 9), (7, 2)]

12. 使用sorted()与reversed()对列表进行局部排序或局部反转

a = [4, 3, 1, 2, 0]

a[:4] = reversed(a[:4]) 
print(a)
# [2, 1, 3, 4, 0]

a[:4] = sorted(a[:4]) 
print(a)
# [1, 2, 3, 4, 0]

13. filter()

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

def is_odd(n):
    return n % 2 == 1
 
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)

[1, 3, 5, 7, 9]

14. 排列与组合

itertools.permutations()罗列排列可能性。
itertools.combinations()罗列组合可能性。

import itertools

list1 = [1, 2, 3]

# 包含3个值的情况下所有的排列可能性
list2 = list(itertools.permutations(list1,3))
print(list2)
# [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

# # 包含3个值的情况下所有的组合可能性
list3 = list(itertools.combinations(list1,2))
print(list3)
# [(1, 2), (1, 3), (2, 3)]

15. 阶乘factorial()

import math
num = math.factorial(6)
print(num)

16. repr()处理转义字符

当遇到需要从cmd或者文件输入路径,例如路径"E:\V1R2\product\fpgadrive.c",然后需要截取出最后的文件名时,可能遇到/f被判断为单个字符,导致无法正确识别出最后一个/的位置。
对代码中的字符串,可以简单地通过在代码前方加入r来解决,但是对于读取的字符串,只能使用变量名对其进行操作。
此时可以使用repr(input)来获取原始字符串输入然后通过搜索//来获取文件名。
注:repr(input)会导致字符串开头和最后的字符变为’,可以通过[1:-1]的方式去除。

a = repr(input())
# 输入E:\V1R2\product\fpgadrive.c
print(a)
# 'E:\\V1R2\\product\\fpgadrive.c'
a = a[1:-1]
print(a)
# E:\\V1R2\\product\\fpgadrive.c
for i in range(len(a)-1,-1,-1):
	if a[i] == "\\":
		print(a[i+1:])
		# fpgadrive.c
		break

17. 未知输入行数的cmd输入中止判断

基于异常捕获

while True:
    try:
        deal_with(input())
    except:
        break

基于sys
注:该方法会导致读取到的line在末尾有一个\n的换行符,可能导致某些题目中输出出现额外的换行错误。

import sys
while True:
    line = sys.stdin.readline()
    if not line:
        break
    deal_with(line)

18. 高阶矩阵深拷贝

在不使用Numpy的情况下,对python原本的列表可以使用[:]进行深拷贝,但如果列表为二阶矩阵及以上时,深拷贝对内部的元素产生的效果依然只是浅拷贝,这时候可以通过调用copy库解决。

import copy
a = [[1,2],[3,4]]
b = copy.deepcopy(a)

19. 字符串大小写转换

s.upper() #把所有字符中的小写字母转换成大写字母
s.lower() #把所有字符中的大写字母转换成小写字母
s.capitalize() #把第一个字母转化为大写字母,其余小写
s.title() #把每个单词的第一个字母转化为大写,其余小写 

20. 随机数生成

# 生成 0 ~ 2 之间的随机数
import random
 
print(random.randint(0,2))

21. 进制转换

十进制转换到其它进制
二进制:bin()
八进制:oct()
十六进制:hex()

22. 统计每个元素的出现次数

from collections import Counter
string = "asfhaisfhaoif"
res = Counter(string)
print(res)
# Counter({'a': 3, 'f': 3, 's': 2, 'h': 2, 'i': 2, 'o': 1})

23. 用位运算判断奇数偶数

'''
判断奇偶  (二进制数以1结尾是奇数,以0结尾是偶数)

奇数&1==1

偶数&1==0
'''
print(6&1)
# 0
print(9&1)
# 1

24. 将对象储存在磁盘上

使用pickle将任意python对象保存在磁盘上用于下次调用。

pickle.dump(obj, file[, protocol])
  序列化对象,并将结果数据流写入到文件对象中。参数protocol是序列化模式,默认值为0,表示以文本的形式序列化。protocol的值还可以是1或2,表示以二进制的形式序列化。

pickle.load(file)
  反序列化对象。将文件中的数据解析为一个Python对象。

import pickle  

a = ["fafa",(24,55)]
# 写入二进制文件
with open("pickle_test.pkl","wb") as f:
	pickle.dump(a,f,1)
	
# 读出二进制文件
with open("pickle_test.pkl","rb") as f:
	b=pickle.load(f)

print(b)
# ['fafa', (24, 55)]

25. 用字典的值进行排序

原文链接:https://blog.csdn.net/u013193903/article/details/81096367

# 现在想对字典进行排序,根据value的第一个值,即列表的第一个数字
test_dict = {
    'a': [1, 'n'],
    'b': [2, 'k', 'b'],
    'c': [5, 'h1', 'h2', 'h3', 'h4', 'h5'],
    'd': [3, 'dfg1', 'dfg2', 'df3'],
    'e': [4, 'dfg1', 'dfg2', 'dfg3', 'dfg4'],
    'f': [2, 'dfgl', 'dfg2'],
    'g': [2, 'f1', 'f2'],
}

tmp = sorted(test_dict.items(), reverse=True, key=lambda x: x[1][0])

# >>> test_dict.items()
# dict_items([('a', [1, 'n']), ('b', [2, 'k']), ('c', [5, 'h']), ('d', [10, 'dfg']), ('e', [4, 'dfg']), ('f', [2, 'dfgl']), ('g', [2, 'f'])])
# 这里的test_dict.items()实际上是将test_dict转换为可迭代对象
# ('a', [1, 'n']), ('b', [2, 'k']), ('c', [5, 'h']), ('d', [10, 'dfg']), ('e', [4, 'dfg']), ('f', [2, 'dfgl']), ('g', [2, 'f'])

# 用的是元组的第二值,即列表,取列表的第一个值,就是需要排列的数字,key=lambda x: x[1][0]

26. ASCII码与字符相互转换

# 用户输入字符
c = input("请输入一个字符: ")
 
# 用户输入ASCII码,并将输入的数字转为整型
a = int(input("请输入一个ASCII码: "))
 
 
print( c + " 的ASCII 码为", ord(c))
print( a , " 对应的字符为", chr(a))

27. 将字符串作为代码执行

转自:https://www.runoob.com/python/python-func-eval.html

eval() 函数用来执行一个字符串表达式,并返回表达式的值。

>>>x = 7
>>> eval( '3 * x' )
21
>>> eval('pow(2,2)')
4
>>> eval('2 + 2')
4
>>> n=81
>>> eval("n + 4")
85

27. 字符串开头或结尾

函数:startswith()
作用:判断字符串是否以指定字符或子字符串开头。
函数:endswith()
作用:判断字符串是否以指定字符或子字符串结尾。

a = "fadvfadg"
b = "fad"
print(a.startswith(b))

28. 在python3中使用cmp

sorted(list)函数用于自定义排序规则,key属性为一个方法,返回一个值作为比较的依据。
cmp属性为一个方法,获取x, y两个值,返回正数表示x大于y,否则y大于x。
但是python3取消了cmp属性,需要使用functools.cmp_to_key来转换。

def minNumber(self, nums: List[int]) -> str:
    # 自定义一段字符串拼接来比较大小的函数
    def compare(str1, str2):
        if int(str1+str2) < int(str2+str1):
            return -1
        else:
            return 1
    chars = ''.join(sorted(map(lambda x:str(x),nums), key = functools.cmp_to_key(compare)))

    return chars

29. 通过iter()与next()挨个取出迭代器中的元素

import itertools

a = [1, 2, 3, 4]
# 将普通列表转换为迭代器
b = iter(a)
try:
    while True:
        print(next(b))
except StopIteration:
    print("输出结束")
    
'''
1
2
3
4
输出结束
'''

# 对库函数返回的迭代器逐个输出
results = itertools.permutations(a, len(a))
try:
    while True:
        print(next(results))
except StopIteration:
    print("输出结束")
'''
(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)
输出结束
'''

30. 在异步函数中限时执行同步函数,如何为无法传参的调用函数传参

能够超时报错,但是已经开始的执行无法终止。
使用 functools.partial()传参。

import asyncio
import time
from functools import partial

def test(msg):
    print("函数开始")
    time.sleep(5)
    print("函数完成了",msg)
    return msg

async def main():
    try:
        print("准备开始")
        loop = asyncio.get_running_loop()
        base = partial(test, msg="根本停不下来")
        future = loop.run_in_executor(None, base)
        result = await asyncio.wait_for(future, timeout=3, loop=loop)
        print(result)
    except asyncio.TimeoutError:
        print("超时警告")

asyncio.run(main())

'''
准备开始
函数开始
超时警告
函数完成了 根本停不下来
'''

实验证明,在执行到时间限制时,确实发出了超时警报,但是根本无法终止已经开始的同步函数执行……

31. 从列表与字典中随机获取值

import random

# 从有len()的可迭代对象中获取随机值
a = [1, 2, 3, 4, 5]
result = random.choice(a)
print(result)

b = {1:241, 2:4141, 3:141}
# 随机返回k个值
result = random.sample(b.items(), k=1)
print(result)

32. 单个元素的元组用,标注

单个元素的元组不用, 标注的话会被作为运算符的括号处理。

a = (1)
print(a)
# 1

a = (1,)
print(a)
# (1,)

33. Numpy矩阵填充某个值,或某个矩阵

import numpy as np

# 创建一个500x500x3的图片矩阵并将所有值设为255
img = np.empty([500, 500, 3], dtype=np.uint8)
img.fill(255)

# 创建一个500x500x3的图片矩阵并将所有像素设为[100, 255, 0]
color = np.array([100, 255, 0],dtype=np.uint8)
img = np.tile(color, (500, 500, 1))

34. 将多行文本作为图片保存到磁盘

from PIL import Image, ImageFont, ImageDraw
# 将文本转换为图片保存
def text_to_image(text, img_path):
    lines = text.splitlines()
    # 自适应调整图片长宽
    width = len(max(lines, key=len)) * 20
    height = len(lines) * 22
    img = Image.new("RGB", (width, height), (255, 255, 255))
    dr = ImageDraw.Draw(img)
    # 宋体
    font = ImageFont.truetype(os.path.join("fonts", "simsun.ttc"), 18)
    dr.text((10, 5), text, font=font, fill="#000000")
    # 保存
    img.save(img_path)

35. 使用yield关键词创建迭代器

迭代器可以使得对象在每次运行中返回一个值,而不会一次性返回所有值塞爆内存。

# 创建一个迭代器,在每次执行中返回yield的值
def from_0_plus_1(end):
    num = 0
    while num <= end:
        yield num
        num += 1


nums = from_0_plus_1(5)
print(type(nums))
# <class 'generator'>

# 从迭代器中取出值
while True:
    try:
        print(next(nums))
    # 发生异常说明全部取出
    except StopIteration:
        break
# 0
# 1
# 2
# 3
# 4
# 5

36. isinstance() 判断类型

# isinstance() 与 type() :
# type() 不会认为子类是一种父类类型,不考虑继承关系。
# isinstance() 会认为子类是一种父类类型,考虑继承关系。

# 用法
for name, module in G_model.named_modules():
    if isinstance(module, nn.BatchNorm1d):
        pass

37. import指定路径下的代码文件

import sys
# 例如上一级路径
sys.path.append('..')
import xxx

38. python执行cmd或bash命令

import os

os.system("mkdir new_dir")

39. 按照文件浏览器文件名排序

不是按照字符串,而是按照电脑本地文件浏览器中的排序方式对文件名进行排序。
用于在对少量数据进行效果展示以便debug时使用。

from natsort import natsorted

a = ['abc.jpg', 'def.png']
a = natsorted(a)

40. 判断是否为None

if a is None:

41. 只遍历第一层目录

dirs = os.listdir(root)

42. np.array与np.mat

np.mat才是真正的矩阵类,相乘时基于矩阵乘法
np.array的乘法是逐位相乘,与之不同

43. 谷歌翻译API

安装

pip install googletrans==3.1.0a0

使用(翻译成英文)

from googletrans import Translator

translater = Translator()
out = translater.translate("你好", dest='en', src='auto')
print(out.text)

44. 递归创建目录并且不对已存在的目录报错

import os
os.makedirs(dirname, exist_ok=True)

45. rstip()未解之谜

在参数开头加入了_后,出现了非常奇怪的结果。

print('174585652534_0.png_1020.png'.rstrip('1020.png'))
print('174585652534_0.png_1020.png'.rstrip('_1020.png'))
print('174585652534_0.png_1020.png'.rstrip(r'_1020.png'))

得到

174585652534_0.png_
174585652534
174585652534

重新测试了lstrip(),发现只要在参数开头加入_就会产生奇怪的结果:

print('1020_0.png_1020.png'.lstrip('1020_'))
print('1020_0.png_1020.png'.lstrip('1020'))

print('_1020_0.png_1020.png'.lstrip('_1020_'))
print('_1020_0.png_1020.png'.lstrip('_1020'))

得到

.png_1020.png
_0.png_1020.png
.png_1020.png
.png_1020.png

导致这个奇怪现象的原因暂时仍未找到

46. plt画图

折线图

from matplotlib import pyplot as plt

x = []
y = []

plt.plot(x, y)
plt.show()

3D点云图

import matplotlib.pyplot as plt

fig = plt.figure()
# ax = fig.gca(projection="3d")
ax = fig.add_subplot(projection="3d")

x=[0, 0]
y=[1, 0]
z=[1, 0]

ax.scatter(x,y,z,zdir="z",c="blue",s=1)
ax.scatter(2,3,1,zdir="z",c="red",s=20)

# 随机颜色
color = (random.randint(0,255)/255, random.randint(0,255)/255, random.randint(0,255)/255)
colors = [color for _ in range(len(x))]
ax.scatter(x, y, z, zdir="z", c=colors, s=1)

plt.show()

47. 通过.sh脚本运行conda虚拟环境

# 在sh脚本中直接执行conda虚拟环境
~/anaconda3/envs/ENV_NAME/bin/python test.py

48. 捕获异常并打印

try:
    test()
except Exception as exception:
    print(exception)

49. 多线程/多进程map

多进程

from multiprocessing import Pool

def map_function(data):
    print(data)

with Pool(core_number) as p:
    p.map(map_function, data_list)

注:子进程内不可以再次创建子进程的子进程,只能创建子线程。

多线程

# 只要修改第一行
from multiprocessing.dummy import Pool

注:与python默认的map()不同,pool.map()只支持一个迭代器参数的输入,如果需要使用多个迭代器输入,需要使用zip()打包后再输入,否则会出现报错:

<=' not supported between instances of 'typeA' and 'int'

多线程任务分块与进度打印

能够极大加快例如大批量磁盘读写的运行速度

from multiprocessing.dummy import Pool
import tqdm

# 将大任务拆分为多线程执行的小块用于打印进度
def split_work_parts(data):
    # 工作处理模块长度,仅用于进度打印和批处理分配,不影响效果
    work_part_len = 1280
    
    work_parts = []
    start_i = 0
    while (start_i < len(data)):
        work_parts.append(data[start_i:start_i + work_part_len])
        start_i += work_part_len
        
    return work_parts

# 拆分任务块
work_parts = split_work_parts(datas)
    
# 实际处理的内部逻辑
def map_function(data):
    pass

# 分块处理
for work_part in tqdm.tqdm(work_parts):
    # 分配16个线程处理单个任务块
    with Pool(16) as p:
        p.map(map_function, work_part)

50. 设定命令行参数

import argparse

parser = argparse.ArgumentParser(description='test input parsers')
parser.add_argument('--parserA',  metavar='parserA', nargs='?', help='aaaaa')
parser.add_argument('--parserB', metavar='parserB',  default="0", help='bbbbb')

51. 调用windows语音tts接口

import win32com.client

spk = win32com.client.Dispatch("SAPI.SpVoice")
spk.Speak("早上好")

52. 为字典添加新信息的子信息同时处理原本不存在的键

dict1.setdefault(key1,{})[child_key1] = value1

53. 调用打包在文件夹中的python环境与更新库内容

# 设置环境变量
set ANY_PATH=test\\test.exe
# 更新虚拟环境库
env\\python\\python.exe -m pip install numpy
# 调用虚拟环境中的python执行
env\\python\\python.exe test.py --test_num 123456

54. 按照文件修改时间用数字编号批量重命名

import os

# 修改的目录,只支持单级目录
dir_path = "test"
files = os.listdir(dir_path)

# 按照修改时间递增排序
if files:
    files = sorted(files, key=lambda x: os.path.getmtime(os.path.join(dir_path, x)))

name_length = len(str(len(files)))

for i in range(len(files)):
    # 新的数字编号名,前面补全0
    new_path = os.path.join(dir_path, '0' * (name_length-len(str(i+1))) + str(i+1) + os.path.splitext(files[i])[1])
    # 自动重命名
    # print(os.path.join(dir_path, files[i]), new_path)
    os.rename(os.path.join(dir_path, files[i]), new_path)

或者,使用修改时间重命名文件

# 修改的目录,只支持单级目录
dir_path = r"test"
files = os.listdir(dir_path)

for file in files:
    timestamp = int(os.path.getmtime(os.path.join(dir_path, file)))
    date = datetime.datetime.fromtimestamp(timestamp)
    str = f"{date.year}-{date.month}-{date.day}-{date.hour}-{date.minute}-{date.second}"
    os.rename(os.path.join(dir_path, file), os.path.join(dir_path, str + os.path.splitext(file)[1]))

55. 高精度纳秒计时器

import time
current_time = time.perf_counter_ns()
print(current_time)

56. 进度显示与运行时间预测tqdm

import tqdm

# 使用任何一个用于循环的迭代器
list1 = list(range(100))

for i in tqdm.tqdm(list1):
    pass

57. 判断点是否在多边形内,距离多远

基于matplotlib(不靠谱,已放弃)

import matplotlib
# 用2阶list构造多边形边界
shape = matplotlib.path.Path(shape_points)
# 判断多个点是否在多边形内,如果是判断单个点将用contains_point
result = shape.contains_points(test_points, radius=threshold)

实测radius越小,在边界外面越远的点就会被包含在内,这与文档描述相反。
后来发现原因是threshold值正负效果会变反和给的顺时针逆时针有关。
如果把放入matplotlib.path.Path的输入逆序,效果也会相反。

基于opencv(实测靠谱)

opencv的一次只能判断1个点是否在形状内

# measureDist=True时返回带正负的准确距离值,否则返回measureDist
# 若为False,会找点是否在内,外,轮廓上(+1, -1, 0)
result = cv2.pointPolygonTest(shape_points, point, measureDist=True)

58. 放回抽样与不放回抽样

import random
# 数据集
data = []

# 放回抽样
sample = random.choice(data)

# 不放回抽样
num = 1000
sample = random.sample(data, k=num)

59. 整数开头补全到指定长度

f"{a:07d}"

转换为7位整数自动补0

60. 矩阵批量距离计算

from scipy.spatial.distance import pdist, squareform
# 欧几里得距离
# 返回一个距离矩阵
distance_matrix = pdist(X, 'euclidean')

61. 限制函数调用频率

from ratelimit import limits, sleep_and_retry
from ratelimit.exception import RateLimitException

# 一秒内最多调用2次,否则抛出异常
@limits(calls=2, period=1)
# @sleep_and_retry
def function():
    passs

try:
    function()
# 超时异常
except RateLimitException:
    pass

62. 局部变量字典locals()

locals() ,以字典类型返回当前位置的全部局部变量。
特殊用途:给一些特殊的模块输入路径之类不好直接导入的内容。
例如给Tortoiseinit()输入模块位置配置时,直接输入.models会报错,就可以采用:

from . import models

await Tortoise.init(db_url=database_path,
    modules={"models": [locals()["models"]]})

63. 自定义对象的print内容

修改自定义对象(例如一个类)在被print()调用时输出的内容。
通过定义它的def __str__()函数实现,即它被转换为字符串的方法。

64. 将文件夹压缩成zip压缩包

import zipfile

# 压缩
# 压缩
def zip_file(src_dir, zip_name):
    z = zipfile.ZipFile(zip_name,'w',zipfile.ZIP_DEFLATED)
    length = 0
    count = 0
    for dirpath, _, filenames in os.walk(src_dir):
        fpath = dirpath.replace(src_dir, '/')
        fpath = fpath and fpath + os.sep or '/'
        length += len(filenames)
        for filename in filenames:
            z.write(os.path.join(dirpath, filename),os.path.split(src_dir)[1]+fpath+filename)
            count += 1
            print(f'\rzip file: {count}/{length}', end='')
    print (f'\nzip {src_dir} success!')
    z.close()

65. 模块暴露接口__all__

__all__ = [a, b]

该代码文件对外暴露a和b两个函数接口。
会影响from xxx import *的结果。

66. 安全检查断言assert

assert a = 1

表达式为False会产生异常终止程序。

67. 允许numpy加载pkl数据

np.load(allow_pickle=True)

68. 将字典转换为类成员变量

__dict__.update()

69. 关闭主线程时,子线程退出且不报错

# 创建线程
self.thread = threading.Thread(target=self.function)
# 配置主线程关闭时一起退出
self.thread.setDaemon(True)
# 启动线程
self.thread.start()

70. 方法名中的下划线

参考:Python中下划线的5种含义

单前导下划线:_function
无实际影响,一般代表仅供内部使用

单末尾下划线:function_
用于避开和关键词重复的命名

双前导下划线:__function
无法被从外部以实例调用

双前导和末尾下划线:__function__
特殊预留方法

71. pip和conda查看可安装的版本

以numpy库为例:

pip search numpy
conda search numpy

72. 不关闭文件的情况下将输入流保存到磁盘

# python将file.write()的内容在不关闭的情况下写到磁盘
file.flush()

73. 根据指定不连续索引提取对应元素

from operator import itemgetter
filter_result = itemgetter(*index_list)(data_list)

或者,numpy可以使用np.take()

74. 用numpy保存python的pkl数据

# 样例:字典数据
# 保存
np.save(path, data, allow_pickle=True)
# 读取
data = np.load(path, allow_pickle=True).item()

75. 使用print打印彩色文字

from termcolor import colored
text = f'The message is: {msg}'
# 打印红色
print(colored(text, "red", attrs=["bold"]))

76. 抛出数值异常

raise ValueError(f"Error.")

77. 统计numpy矩阵中像素大于100的值的个数

np.sum(data>100)

78. 用子线程启动和关闭应用程序,判断是否运行

# 启动
Config.frp = subprocess.Popen(["start", Config.frp_path, "-c", Config.frp_config])

# 关闭
Config.frp.kill()

判断一个程序是否运行

# 检测程序是否在运行
def is_program_running(program_name):
    # 扫描所有的进程id
    for pid in psutil.pids():
        try:
            # 如果进程名与服务器名一致,代表服务器正在运行
            if psutil.Process(pid).name() == program_name:
                return True
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    # 扫描所有进程后,未找到服务器
    return False

注:Config.frp_path为完整的绝对路径,而program_name只是文件名,例如frp.exe

79. 检测端口是否可访问

import requests

address = r"http://localhost:12450"
# 检测端口是否正常开放
def is_port_opening(address):
    try:
        response = requests.get(address)
        if response.status_code == 200:
            return True
        else:
            return False
    except:
        return False

80. 读取yaml文件转换为类属性

# 加载字典初始化的类
class Config:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

def get_train_config(config_path):
    # 读取yaml文件转换为字典
    with open(config_path, 'r') as file:
        yaml_data = yaml.load(file, Loader=yaml.FullLoader)
    # 将字典转换为类对象
    config = Config(**yaml_data)
    # 返回类对象
    return config

81. 读写带中文的json数据

# 写带中文的json
with open(os.path.join(data, "data.json"), 'w', encoding='utf-8') as f:
    json.dump(test_dataset, f, ensure_ascii=False, indent=4)

# 读带中文的json
with open("data.json", 'r', encoding='utf-8') as data_file:
    self.data = json.load(data_file)

82. 配置yaml输出顺序与换行

sort_keys=False使得输出的YAML文件中的键的顺序与原始字典的顺序一致。
width=200决定了输出的文件在满足多大宽度后会自动换行。

with open('output.yaml', 'w') as file:
    yaml.dump(data, file, default_flow_style=False, allow_unicode=True, sort_keys=False, width=200)

83. 一些通用文件读写方法(json, yaml, raw, pkl)

# 读写配置文件
def read_json(file_path):
    with open(file_path, 'r', encoding='utf-8') as json_file:
        json_data = json.load(json_file)
    return json_data


def write_json(file_path, json_data):
    with open(file_path, 'w', encoding='utf-8') as json_file:
        json.dump(json_data, json_file, ensure_ascii=False, indent=4)


def read_yaml(file_path):
    with open(file_path, 'r', encoding='utf-8') as yaml_file:
        yaml_data = yaml.safe_load(yaml_file)
    return yaml_data


def write_yaml(file_path, yaml_data):
    with open(file_path, 'w', encoding='utf-8') as yaml_file:
        yaml.dump(data=yaml_data, stream=yaml_file, allow_unicode=True, default_flow_style=None, sort_keys=False,
                  width=200)


# 读写raw数据
def read_raw(file_path, dtype=np.float32, shape=(1, -1, 2)):
    return np.fromfile(file_path, dtype=dtype).reshape(*shape)


# raw_data为numpy格式
def write_raw(file_path, raw_data):
    with open(file_path, "w") as raw_file:
        raw_data.tofile(raw_file)


# 对任意数据的读写
def save_data(data, file_path):
    with open(file_path, 'wb') as file:
        pickle.dump(data, file)


def load_data(file_path):
    with open(file_path, 'rb') as file:
        data = pickle.load(file)
    return data

84. 分割连续多个空格或制表符

Python的split()函数在没有参数的情况下,会默认把所有的空白字符(包括空格、换行、制表符等)作为分隔符,并且会自动忽略连续的分隔符。也就是说,如果你的字符串中有多个连续的空格或制表符,split()函数会把它们当作一个分隔符处理,不会产生空元素。

85. conda克隆虚拟环境

conda create --clone 已有虚拟环境路径 --prefix 生成目标环境路径

86. numpy.array与numpy.mat的矩阵乘法

@:这是Python 3.5及更高版本中引入的一个新运算符,用于进行矩阵乘法。例如,如果A和B都是NumPy数组,那么A @ B会进行矩阵乘法。
*:这个运算符在处理NumPy数组时执行元素级别的乘法,而不是矩阵乘法。也就是说,A * B会生成一个新的数组,新数组的每个元素都是A和B中对应元素的乘积。
如果你使用np.mat创建了矩阵,那么使用*运算符会执行矩阵乘法,这与使用np.array并用@运算符执行的操作是等价的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值