lambda本质上是一个写在一行中的函数, 冒号左侧为函数输入值,右侧为返回值,可以有多个输入和返回。
lambda x:x+1
lambda x, y:x+y
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]))
current_path = os.path.split(os.path.realpath(__file__))[0]
当输入是一个未定长度的列表,而函数输入要求所有变量分别输入时,使用*将列表中的每个元素单独展开作为变量输入。
在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)]
会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 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]))
& 按位与运算符
| 按位或运算符
^ 按位异或运算符:当两对应的二进位相异时,结果为1
~ 按位取反运算符
<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。
同:>> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数
例:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。使用异或运算得到结果。
def singleNumber(nums):
return reduce(lambda x, y: x ^ y, nums)
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]
# 查询第一个指定元素的位置
index = list_1.index(element)
识别字符串开头的数字,代码与说明转自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个或多个
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标。
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print(list(enumerate(seasons)))
[(0, ‘Spring’), (1, ‘Summer’), (2, ‘Fall’), (3, ‘Winter’)]
# 导入库
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)]
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]
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]
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)]
import math
num = math.factorial(6)
print(num)
当遇到需要从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
基于异常捕获
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)
在不使用Numpy的情况下,对python原本的列表可以使用[:]进行深拷贝,但如果列表为二阶矩阵及以上时,深拷贝对内部的元素产生的效果依然只是浅拷贝,这时候可以通过调用copy库解决。
import copy
a = [[1,2],[3,4]]
b = copy.deepcopy(a)
s.upper() #把所有字符中的小写字母转换成大写字母
s.lower() #把所有字符中的大写字母转换成小写字母
s.capitalize() #把第一个字母转化为大写字母,其余小写
s.title() #把每个单词的第一个字母转化为大写,其余小写
# 生成 0 ~ 2 之间的随机数
import random
print(random.randint(0,2))
十进制转换到其它进制
二进制:bin()
八进制:oct()
十六进制:hex()
from collections import Counter
string = "asfhaisfhaoif"
res = Counter(string)
print(res)
# Counter({'a': 3, 'f': 3, 's': 2, 'h': 2, 'i': 2, 'o': 1})
'''
判断奇偶 (二进制数以1结尾是奇数,以0结尾是偶数)
奇数&1==1
偶数&1==0
'''
print(6&1)
# 0
print(9&1)
# 1
使用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)]
原文链接: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]
# 用户输入字符
c = input("请输入一个字符: ")
# 用户输入ASCII码,并将输入的数字转为整型
a = int(input("请输入一个ASCII码: "))
print( c + " 的ASCII 码为", ord(c))
print( a , " 对应的字符为", chr(a))
转自: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
函数:startswith()
作用:判断字符串是否以指定字符或子字符串开头。
函数:endswith()
作用:判断字符串是否以指定字符或子字符串结尾。
a = "fadvfadg"
b = "fad"
print(a.startswith(b))
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
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)
输出结束
'''
能够超时报错,但是已经开始的执行无法终止。
使用 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())
'''
准备开始
函数开始
超时警告
函数完成了 根本停不下来
'''
实验证明,在执行到时间限制时,确实发出了超时警报,但是根本无法终止已经开始的同步函数执行……
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)
单个元素的元组不用, 标注的话会被作为运算符的括号处理。
a = (1)
print(a)
# 1
a = (1,)
print(a)
# (1,)
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))
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)
迭代器可以使得对象在每次运行中返回一个值,而不会一次性返回所有值塞爆内存。
# 创建一个迭代器,在每次执行中返回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))
#
# 从迭代器中取出值
while True:
try:
print(next(nums))
# 发生异常说明全部取出
except StopIteration:
break
# 0
# 1
# 2
# 3
# 4
# 5
# isinstance() 与 type() :
# type() 不会认为子类是一种父类类型,不考虑继承关系。
# isinstance() 会认为子类是一种父类类型,考虑继承关系。
# 用法
for name, module in G_model.named_modules():
if isinstance(module, nn.BatchNorm1d):
pass
import sys
# 例如上一级路径
sys.path.append('..')
import xxx
import os
os.system("mkdir new_dir")
不是按照字符串,而是按照电脑本地文件浏览器中的排序方式对文件名进行排序。
用于在对少量数据进行效果展示以便debug时使用。
from natsort import natsorted
a = ['abc.jpg', 'def.png']
a = natsorted(a)
if a is None:
dirs = os.listdir(root)
np.mat才是真正的矩阵类,相乘时基于矩阵乘法
np.array的乘法是逐位相乘,与之不同
安装
pip install googletrans==3.1.0a0
使用(翻译成英文)
from googletrans import Translator
translater = Translator()
out = translater.translate("你好", dest='en', src='auto')
print(out.text)
import os
os.makedirs(dirname, exist_ok=True)
在参数开头加入了_后,出现了非常奇怪的结果。
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
导致这个奇怪现象的原因暂时仍未找到
折线图
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()
# 在sh脚本中直接执行conda虚拟环境
~/anaconda3/envs/ENV_NAME/bin/python test.py
try:
test()
except Exception as exception:
print(exception)
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)
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')
import win32com.client
spk = win32com.client.Dispatch("SAPI.SpVoice")
spk.Speak("早上好")
dict1.setdefault(key1,{})[child_key1] = value1
# 设置环境变量
set ANY_PATH=test\\test.exe
# 更新虚拟环境库
env\\python\\python.exe -m pip install numpy
# 调用虚拟环境中的python执行
env\\python\\python.exe test.py --test_num 123456
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]))
import time
current_time = time.perf_counter_ns()
print(current_time)
import tqdm
# 使用任何一个用于循环的迭代器
list1 = list(range(100))
for i in tqdm.tqdm(list1):
pass
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的一次只能判断1个点是否在形状内
# measureDist=True时返回带正负的准确距离值,否则返回measureDist
# 若为False,会找点是否在内,外,轮廓上(+1, -1, 0)
result = cv2.pointPolygonTest(shape_points, point, measureDist=True)
import random
# 数据集
data = []
# 放回抽样
sample = random.choice(data)
# 不放回抽样
num = 1000
sample = random.sample(data, k=num)
f"{a:07d}"
转换为7位整数自动补0
from scipy.spatial.distance import pdist, squareform
# 欧几里得距离
# 返回一个距离矩阵
distance_matrix = pdist(X, 'euclidean')
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
locals()
,以字典类型返回当前位置的全部局部变量。
特殊用途:给一些特殊的模块输入路径之类不好直接导入的内容。
例如给Tortoise
的init()
输入模块位置配置时,直接输入.models
会报错,就可以采用:
from . import models
await Tortoise.init(db_url=database_path,
modules={"models": [locals()["models"]]})
修改自定义对象(例如一个类)在被print()
调用时输出的内容。
通过定义它的def __str__()
函数实现,即它被转换为字符串的方法。
import zipfile
# 压缩
def zip_file(src_dir):
zip_name = src_dir +'.zip'
z = zipfile.ZipFile(zip_name,'w',zipfile.ZIP_DEFLATED)
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),fpath+filename)
count += 1
print(f'\rzip file: {count}/{length}', end='')
print (f'zip {src_dir} success!')
z.close()
__all__ = [a, b]
该代码文件对外暴露a和b两个函数接口。
会影响from xxx import *
的结果。
assert a = 1
表达式为False会产生异常终止程序。
np.load(allow_pickle=True)
__dict__.update()
# 创建线程
self.thread = threading.Thread(target=self.function)
# 配置主线程关闭时一起退出
self.thread.setDaemon(True)
# 启动线程
self.thread.start()
参考:Python中下划线的5种含义
单前导下划线:_function
无实际影响,一般代表仅供内部使用
单末尾下划线:function_
用于避开和关键词重复的命名
双前导下划线:__function
无法被从外部以实例调用
双前导和末尾下划线:__function__
特殊预留方法
以numpy库为例:
pip search numpy
conda search numpy