github入口
基本操作
1、常见算术运算
# 20210721_Super
# 常见算数运算符
x, y = 3, 2
print(x+y)
# 5
print(x-y)
# 1
print(x*y)
6
print(x/y)
# 1.5
print(x//y) #整数除法,返回商的整数部分
# 1
print(y//x)s
# 0
print(x%y) #返回除法的余数
# 1
print(y%x)
# 2
print(-x)
# -3
print(abs(-x))
# 3
print(x+0.9)
# 3.9
print(int(x+0.9)) #取整
# 3
print(float(x)) #取浮点型
# 3.0
print(x**y) ##x的y次方
9
2、实现relu
#202107210859_Super
#在神经网络中,relu作为神经元的激活函数:
#线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元
def relu(x):
# x:输入参数
# return:输出relu值
return max(0, x)
# 测试
relu(5)
# 5
relu(-1)
# 0
3、进制转化
# 202007210913_Super
# 注:bin(),oct(),hex()返回的均为字符串
# 十进制转换为二进制:
bin(10)
# '0b1010'
# 十进制转换为八进制
oct(9)
# '0o11'
#十进制转换为十六进制
hex(15)
# '0xf'
4、整数和ASCII互转
#202107210932_Super
#整数和ASCLL互转
# 十进制整数对应的ASCII
chr(65)
# 'A'
# 查看某个ASCII字符对应的十进制数
ord('A')
65
5、元素全部为真 检查
# 202107210937_Super
# 元素都为真检查
# 所有元素都为真,返回True,否则为False
all([1, 0, 3, 6])
# False
all([1, 3, 6])
# True
6、至少一个为真 检查
# 至少一个为真 检查
# 至少有一个元素为真返回True,否则为False
any([0, 0, 0, []])
# False
any([0, 0, 1])
# True
7、判断是真是假
# 判断是真是假(布尔型变量)
# 测试一个对象是True,还是False
# 目前理解有东西则为True,没东西则为False
bool([0, 0, 0]) # True
bool([1, 0, 1]) # True
bool('Super') # True
hh = (2, 'Super', 'Market', '小红', "小哒")
print(bool(hh)) # True
bool([]) # False
bool(0) #False
bool('') #False
bool("") #False
bool("") #False
bool({}) #False
bool(()) #False
bool(None) #False
8、创建一个复数
# 创建复数
# 创建一个复数
complex(1,2)
# (1+2j)
9、取商和余数
# 取商和余数
divmod(10, 3)
# (3, 1)
10、转为浮点型
#转为浮点类型
float(3)
# 3.0
#如果不能转为浮点型,则会报ValueError:
float('a')
# ValueError: could not convert string to float: 'a'
11、转为整型
# 转为整型
int(10.0)
# 10
int('12',16)
# 18 不是很明白后面的16
12、次幂
# base(3)为底的exp(2)次幂,如果mod(4)给出,取余(1)
pow(3, 2, 4) #3的2次方再对4取余
# 1
13、四舍五入
# 四舍五入
round(10.02222222, 4)
# 10.0222
round(12.234566788, 6)
# 12.234567
14、链式比较
# 链式比较
i = 3
print(1 < i < 3) #False
print(1 < i <= 3 ) #True
15、字符串转字节
# 字符串转字节
# 字符串转换为字节类型
s = "banana"
bytes(s, encoding = 'utf-8')
# b'banana'
16、任意对象转为字符串
# 15、任意对象转为字符串
i = 100
str(i) # '100'
str([]) # '[]'
str(tuple()) # '()'
17、执行字符串表示的代码
#17、 执行字符串表示的代码
# 将字符串编译成python可识别或可执行的代码,
# 也可以将文字读成字符串再编译
s = "print('HelloWorld')"
r = compile(s, "<string>", "exec")
r
# <code object <module> at 0x000001E650EFF190, file "<string>", line 1>
exec(r)
# HelloWorld
18、计算表达式
# 计算表达式
s = "1+3+5"
eval(s) # 9
19、字符串格式化
# 字符串格式化
print("I am {0},age {1}".format("Super",18))
# I am Super,age 18
3.1415926 {:.2f} 3.14 保留小数点后两位
3.1415926 {:+.2f} +3.14 带符号保留小数点后两位
-1 {:+.2f} -1.00 带符号保留小数点后两位
2.71828 {:.0f} 3 不带小数
5 {:0>2d} 05 数字补零 (填充左边, 宽度为2)
5 {:x<4d} 5xxx 数字补x (填充右边, 宽度为4)
10 {:x<4d} 10xx 数字补x (填充右边, 宽度为4)
1000000 {:,} 1,000,000 以逗号分隔的数字格式
0.25 {:.2%} 25.00% 百分比格式
1000000000{:.2e} 1.00e+09 指数记法
18 {:>10d} ' 18' 右对齐 (默认, 宽度为10)
18 {:<10d} '18 ' 左对齐 (宽度为10)
18 {:^10d} ' 18 ' 中间对齐 (宽度为10)
20、交换两元素
# 20、交换两元素
def swap(a, b):
return b,a
print(swap(1, 0))
# (0, 1)
21、转换字典
创建数据字典
# 21、转换字典
# 创建数据字典
dict()
# {}
dict(a = 'a', b = 'b')
{'a': 'a', 'b': 'b'}
dict(zip(['a', 'b'], [1, 2]))
# {'a': 1, 'b': 2}
dict([['a', 1],('b', 2)])
# {'a': 1, 'b': 2}
22、冻结集合
创建一个不可修改的集合
# 22、冻结集合
# 创建一个不可修改的集合
frozenset([1, 1, 3, 2, 3])
# frozenset({1, 2, 3})
# 因为不可修改,所以没有像set那样的add和pop方法
23、转为集合类型
返回一个set对象,集合内不允许有重复元素
# 23、转为集合类型
# 返回一个set对象,集合内不允许有重复元素
a = [1, 4, 2, 3, 1]
set(a)
# {1, 2, 3, 4}
24、转元组
tuple()函数将对象转为一个不可变的序列类型
# 24、转元组
# tuple()函数将对象转为一个不可变的序列类型
i_am_list = [1, 3, 5]
i_am_list
# [1, 3, 5]
i_am_tuple = tuple(i_am_list)
i_am_tuple
# (1, 3, 5)
25、查看变量所占字节数
# 查看变量所占字节数
import sys
a = {'a':1,'b':2.0}
a
sys.getsizeof(a) #占用232个字节
# 232
26、含单个元素的元组
不是很理解
# 含单个元素的元组
# Python中有些函数的参数类型为元组,其内有1个元素,这样创建是错误的
c = (5) #NO
c # 5
# 它实际上创建一个整型元素5,必须要在元素后加上一个逗号
c = (5,) #YES
c
# (5,)
27、列表删除之坑
# 列表删除之坑
# 删除一个列表中的元素,此元素可能在列表中重复多次
def del_item(lst,e):
return [lst.remove(i) for i in e if i == e] #NO!
# 考虑删除这个序列[1,3,3,3,5]的元素3,结果发现只删除两个:
del_item([1,3,3,3,5],3)
# 正确做法
def del_item1(lst,e):
d = dict(zip(range(len(lst)),lst)) #YES,构造字典
return [v for k, v in d.items() if v!=e]
del_item1([1,3,3,3,5],3)
# [1, 5]
28、列表快速复制之坑
# 列表快速复制之坑
# 在python中*与列表操作,实现快速元素复制
a = [1,3,5] * 3
a
# [1, 3, 5, 1, 3, 5, 1, 3, 5]
a[0] = 10
a
# [10, 3, 5, 1, 3, 5, 1, 3, 5]
# 如何列表元素为列表或字典等复合类
a = [[1,3,5], [2,4]]*3
a
# [[1, 3, 5], [2, 4], [1, 3, 5], [2, 4], [1, 3, 5], [2, 4]]
a[0][0] = 10
a
#结果发现,a[1][0],a[2][0]也被修改为10
# [[10, 3, 5], [2, 4], [10, 3, 5], [2, 4], [10, 3, 5], [2, 4]]
# 这是因为*复制的复合对象都是浅引用,也就是说id(a[0])与id(a[2])门牌号是相等的。
# 如果想要实现深复制效果,这么做:
b = [[[1,3,5], [2,4]] for _ in range(3)]
b
# [[[1, 3, 5], [2, 4]], [[1, 3, 5], [2, 4]], [[1, 3, 5], [2, 4]]]
b[0][0][0] = 10
b
# [[[10, 3, 5], [2, 4]], [[1, 3, 5], [2, 4]], [[1, 3, 5], [2, 4]]]
29、找出列表前3个最大或最小数
# 找出列表前3个最大或最小数
# 使用堆模块heapq里的nlargest
import heapq as hq
nums_list = [25, 35, 22, 85, 14, 65, 75, 22, 58]
#find three largest values
largest_nums = hq.nlargest(3, nums_list)
largest_nums
# [85, 75, 65]
#find three smallest values
smallest_nums = hq.nsmallest(3,nums_list)
smallest_nums
# [14, 22, 22]
30、字符串驻留
# 字符串驻留
a = "something"
b = 'some'+'thing'
id(a) == id(b)
# True
#再看一个
a = 'GeoSuper.top'
b = 'GeoSuper'+'.top'
id(a) == id(b)
# False
#这与Cpython编译优化相关,行为称为“字符串驻留”,
# 但驻留的字符串中只包含字母,数字或下划线
31、创建空集合错误
结果应该不对,以后再看
# 创建空集合错误
# 这是Python的一个集合:{1,3,5},它里面没有重复元素,在去重等场景有重要应用。
# 下面创建空集合是错误的。
empty = {} #NO!
empty
# {}
# Cpython会把它解释为字典
# 使用内置函数创建空集合
empty = set()
empty
# set()
32、充分认识for
不是很理解
# 充分认识for
for i in range(5):
print(i)
i = 10
# 为什么不是执行一次就退出?
# 按照for在python中的工作方式,i = 10并不影响循环。
# range(5)生成的下一个元素就被解包,并赋值给目标列表的变量i
33、认识执行时机
不是很理解,需要再看
# 认识执行时机
array = [1, 3, 5]
g = (x for x in array if array.count(x) > 0)
g #为生成器
<generator object <genexpr> at 0x00000208BB297040>
list(g)
# [1, 3, 5]
# 再看
array = [1, 3, 5]
g = (x for x in array if array.count(x) > 0)
array = [5, 7, 9]
list(g)
# [5]
# 不可思议,仅增加了array = [5, 7, 9]
# 原因在于:生成器表达式中,in子句在声明时执行,而条件子句则在运行时执行
# 所以代码:
array = [1, 3, 5]
g = (x for x in array if array.count(x) > 0)
array = [5, 7, 9]
# 约等于
g = (x for x in [1,3,5] if [5,7,9].count(x) > 0)
函数和模块常见用法
34、 操作函数对象
创建函数对象的list,
# 操作函数对象
def f():
print('i\'m f')
def g():
print('i\'m g')
[f,g][0]()
# i'm f
[f,g][1]()
# i'm g
35、创建range序列
生成一个不可变序列
# 35、创建range序列
# 生成逆序序列
# 1、range(stop)
# 2、range(start, stop[, step])
range(11)
# range(0, 11)
range(0,11,1)
# range(0, 11)
36、生成逆序序列
list(range(10, -1, -1))
# [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
list(range(10, 0, -1))
# [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
37、拿来就用的排序函数
# 排序
a = [1, 4, 2, 3, 1]
sorted(a, reverse = True)
# [4, 3, 2, 1, 1]
a = [{'name':'xiaoming', 'age':18, 'gender':'male'},
{'name':'xiaohong', 'age':20, 'gender':'female'},
{'name':'xiaoshub', 'age':26, 'gender':'male'}]
sorted(a, key = lambda x:x['age'], reverse = True)
# [{'name': 'xiaoshub', 'age': 26, 'gender': 'male'},
# {'name': 'xiaohong', 'age': 20, 'gender': 'female'},
# {'name': 'xiaoming', 'age': 18, 'gender': 'male'}]
38、求和函数
# 38、求和函数
a = [1,4,3,2,1]
sum(a)
# 11
sum(a,11)
# 22
sum(a,11,11)
# TypeError: sum() takes at most 2 arguments (3 given)
39、函数的五类参数使用例子
# 39、函数的五类参数使用例子
# python五类参数:位置参数,关键字参数,默认参数,可变位置或关键字参数的使用。
def f(a, *b, c=10, **d):
print(f'a:{a}, b:{b}, c:{c}, d:{d}')
# 默认参数c不能位于可变关键字参数d后
# 调用f:
f(1, 2, 5, width=10, height=20)
# a:1, b:(2, 5), c:10, d:{'width': 10, 'height': 20}
# 可变位置参数b实参后被解析为元组(2,5),而c取得默认值10;d被解析为字典
# 再次调用f
f(a=1, c=12)
# a:1, b:(), c:12, d:{}
# a=1出入时a就是关键字,b,d都未传值,c被传入12,而非默认值。
# 注意观察参数a,既可以f(1),也可以f(a=1)其可读性比第一种更好,建议利用f(a=1)。
# 需要在前面加一个星号:
def f(*, a, **b):
print(f'a:{a},b:{b}')
# 此时f(1)报错:TypeError: f() takes 0 positional arguments but 1 was give
f(1)
# TypeError: f() takes 0 positional arguments but 1 was give
# 只能f(a=1)才能ok
f(a=1)
# a:1,b:{}
# 说明前面的*发挥作用,它变为只能传入关键字参数,那么如何查看这个参数的类型呢?
# 借助python的inspect模块:
from inspect import signature
for name, val in signature(f).parameters.items():
print(name, val.kind)
# a KEYWORD_ONLY
# b VAR_KEYWORD
# 可以看到参数a的类型为KEYWORD_ONLY,也就是仅仅因为关键字参数
# 但是,如果f定义为:
def f(a, *b):
print(f'a:{a},b:{b}')
# 查看参数类型
for name, val in signature(f).parameters.items():
print(name, val.kind)
# a POSITIONAL_OR_KEYWORD
# b VAR_POSITIONAL
# 可以看到参数a既可以是位置参数也可以是关键字参数
40、使用slice对象
频繁使用同一切片的操作可使用slice对象抽出来,复用的同时还能提高代码的可读性
# 40、使用slice对象
# 生成关于蛋糕的序列cake1
cake1 = list(range(5, 0, -1))
cake1
[5, 4, 3, 2, 1]
b = cake1[1:10:2]
b
# [4, 2]
c = cake1[0:10:2]
c
# [5, 3, 1]
#再生成一个序列
from random import randint
cake2 = [randint(1,100) for _ in range(100)]
cake2
# [4, 78, 38, 63, 20, 43, 19, 57, 99, 57, 80, 82, 40, 51, 82, 28, 83, 68, 66,
# 81, 9, 82, 68, 19, 73, 16, 39, 58, 51, 96, 71, 14, 6, 2, 33, 29, 66, 77, 40,
# 80, 58, 36, 40, 49, 88, 62, 43, 83, 10, 12, 11, 61, 87, 98, 28, 32, 75, 60,
# 91, 80, 67, 41, 47, 7, 48, 27, 37, 46, 61, 3, 11, 57, 98, 23, 14, 85, 48, 91,
# 40, 15, 48, 93, 25, 11, 37, 33, 46, 91, 69, 93, 37, 37, 90, 76, 45, 77, 90,
# 18, 8, 5]
d = cake2[1:10:2] #以间隔为2切前十个数
d
# [78, 63, 43, 57, 57]
# 对于逆向序列切片
a = [1, 3, 5, 7, 9, 0, 3, 5, 7]
a_ = a[5:1:-1]
a_
# [0, 9, 7, 5]
named_slice = slice(5,1,-1)
a_slice = a[named_slice]
a_slice
# [0, 9, 7, 5]
# 频繁使用同一切片的操作可使用slice对象抽出来,复用的同时还能提高代码的可读性
41、lambda函数
# 求lambda函数
def max_len(*list):
return max(*list, key=lambda v:len(v))
#有两点疑惑
# 1、参数v的取值
# 2、lambda函数有返回值吗?如果有返回值是多少?
# 调用上述函数,求出以下三个最长的列表
r = max_len([1,2,3],[4,5,6,7],[8])
print(f'最长的列表是{r}')
# 最长的列表是[4, 5, 6, 7]
# 结论:
# 参数v的可能取值为*lists, 也就是tuple的一个元素
# lambda函数返回值,等于lanbda v冒号后表达式的返回值。
42、枚举对象
# 返回一个可以枚举的对象, 该对象的next()方法将返回一个元组里。
s = ["a", "b", "c"]
for i,v in enumerate(s,1):
print(i,v)
# 1 a
# 2 b
# 3 c
43、过滤器filter
# 过滤器filter
# 在函数中设定过滤条件, 迭代元素,保留返回值为True的元素;
fil = filter(lambda x:x>10,[1,11,2,45,7,6,13])
list(fil)
[11, 45, 13]
44、返回对象哈希值
# 44、返回对象哈希值
# 返回对象的哈希值,值得注意的是自定义的实例都是可哈希的;
# list、dict、set等可变对象都是不可哈希的(unhashable)
hash(xiaoming)
# NameError: name 'xiaoming' is not defined
hash([1,2,3])
# TypeError: unhashable type: 'list'
45、带名字的元组
# 定义名字为Point的元组,字段属性有x,y,z
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y', 'z'])
lst = [Point(1.5, 2, 3.0),Point(-0.3, -1.0, 2.1), Point(1.3, 2.8, -2.5)]
print(lst[0].y - lst[1].y)
# 3.0
46、一行代码实现列表反转
## 46、一行代码实现列表反转
def reverse(lst):
return lst[::-1]
r = reverse([1, -2, 3, 4, 1, 2])
r
# [2, 1, 4, 3, -2, 1]
47、反转字符串的两个方法
st = "python"
# 方法1
''.join(reversed(st)) ##注意是两个单引号
# 'nohtyp'
st[::-1]
# 'nohtyp'
48、join串联字符串
# 串联字符串
# 用逗号连接字符串
mystr = ['1', '2', 'java', '4', 'python', 'java', '7', '8', 'java',
'python', '11', 'java', '13', '14']
''.join(mystr)
# '12java4pythonjava78javapython11java1314'
','.join(mystr)
# '1,2,java,4,python,java,7,8,java,python,11,java,13,14'
'_'.join(mystr)
# '1_2_java_4_python_java_7_8_java_python_11_java_13_14'
49、字符串字节长度
def str_byte_len(mystr):
return (len(mystr.encode('utf-8')))
str_byte_len('i love python')
# 13(个字节)
str_byte_len('字符')
# 6(个字节)
50、groupby单字段分组
## groupby单字段分组
# 天气记录:
a = [{'date':'2019-12-15','weather':'cloud'},
{'date':'2019-12-13','weather':'sunny'},
{'date':'2019-12-14','weather':'cloud'}]
# 安装天气字段weather分组汇总:
from itertools import groupby
for k, items in groupby(a,key = lambda x:x['weather']):
print(k)
# cloud
# sunny
# cloud
# 修改代码
a.sort(key=lambda x:x['weather'])
for k, items in groupby(a, key = lambda x:x['weather']):
print(k)
for i in items:
print(i)
# cloud
# {'date': '2019-12-15', 'weather': 'cloud'}
# {'date': '2019-12-14', 'weather': 'cloud'}
# sunny
# {'date': '2019-12-13', 'weather': 'sunny'}
51、groupby多字段分组
## groupby多字段分组
# itemgetter是一个类,itemgetter('weather')返回一个可调用的对象,它的参数可有多个
from operator import itemgetter
from itertools import groupby
a.sort(key = itemgetter('weather','date'))
for k, items in groupby(a, key = itemgetter('weather')):
print(k)
for i in items:
print(i)
# 结果如下,使用weather和date两个字段排序a,
# cloud
# {'date': '2019-12-14', 'weather': 'cloud'}
# {'date': '2019-12-15', 'weather': 'cloud'}
# sunny
# {'date': '2019-12-13', 'weather': 'sunny'}
52、itemgetter和key函数
# itemgetter和key函数
# 注意到sort和groupby所用的key函数,除了lambda写法外,还有一种简写,就是
# 使用itemgetter
a = [{'date':'2019-12-15','weather':'cloud'},
{'date':'2019-12-13','weather':'sunny'},
{'date':'2019-12-14','weather':'cloud'}]
from operator import itemgetter
from itertools import groupby
a.sort(key = itemgetter('weather'))
a
# [{'date': '2019-12-15', 'weather': 'cloud'},
# {'date': '2019-12-14', 'weather': 'cloud'},
# {'date': '2019-12-13', 'weather': 'sunny'}]
for k, items in groupby(a, key = itemgetter('weather')):
print(k)
for i in items:
print(i)
cloud
{'date': '2019-12-15', 'weather': 'cloud'}
{'date': '2019-12-14', 'weather': 'cloud'}
sunny
{'date': '2019-12-13', 'weather': 'sunny'}
53、sum函数计算和聚合同时做
## 53、sum函数计算和聚合同时做
# python中的聚合函数sum,min,max第一个参数是iterable类型,一般使用方法如下:
a = [4, 2, 5, 1]
sum([i+1 for i in a])
# 16
# 使用列表生成式[i+1 for i in a]创建一个长度与a一行的临时列表,这步完成后,
# 再做sum聚合
# 试想如果你的数组a长度是百万级,再创建一个这样的临时列表是很不划算的,
# 最好一边算一边聚合,稍改动为如下:
a = [4, 2, 5, 1]
sum(i+1 for i in a)
# 16
(i+1 for i in a)
# <generator object <genexpr> at 0x000001E01DFAFA50>
#生成器每迭代一步吐出(yield)一个元素并计算和聚合后,进入下一次迭代,直到终点。
54、默认参数设为空
## 默认参数设为空
# 含有默认参数的函数,如果类型为容器,则设置为空
def f(a,b=[]): #No!
print(b)
return b
ret = f(1)
# []
ret.append(1)
ret
# [1]
ret.append(2)
ret
# [1, 2]
f(1)
# [1, 2]
# [1, 2]
# 什么再调用f(1)时,输出不是[]呢?
# 这是可变类型的默认参数之坑,请务必设置此类默认参数为None:
def f(a,b = None): #YES!pass
print(b)
return(b)
ret = f(1)
# None
55、各种参数使用之坑
56、lambda自由参数之坑
## 56、lambda自由参数之坑
a = [lambda x:x+i for i in range(3)] #NO
for f in a:
print(f(1))
# 3
# 3
# 3
# 定义lambda使用的i被称为自由参数,它只在调用lambda函数时,值才被真正确定下来
# 所以正确做法是
a = [lambda x,i=i:x+i for i in range(3)]
for f in a:
print(f(1))
# 1
# 2
# 3
57、使用 堆 排序列表 为升序
# 使用堆排序列表为升序
# 使用heapq模块,首先对列表建堆,默认建立小根堆,调用len(nums)次heappop:
import heapq as hq
nums_list = [18, 14, 10, 9, 8, 7, 9, 3, 2, 4, 1]
hq.heapify(nums_list)
nums_list
# [1, 2, 7, 3, 4, 10, 9, 18, 9, 14, 8]
s_result = [hq.heappop(nums_list)for _ in range(len(nums_list))]
s_result
# [1, 2, 3, 4, 7, 8, 9, 9, 10, 14, 18]