基础
1 求绝对值
求绝对值或复数的模
>>> abs(-6)
6
2 元素都为真
接受一个迭代器,如果迭代器的 所有元素 都为真,那么返回 True ,否则返回 False
>>> all([0,1,2,3])
False
>>> all([1,2,3])
True
3 元素至少一个为真
接受一个迭代器,如果迭代器里 至少有一个 元素为真,那么返回 True ,否则返回 False
>>> any([0,0,0])
False
>>> any([0,0,1]) True
4 ascii展示对象
调用对象的repr() 方法,获得该方法的返回值
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
if __name__ == '__main__':
Xiaoming = Student(1, '小明')
print(Xiaoming)
id=1,name=小明
5 十转二
将 十进制 转换为 二进制
>>> bin(10)
'0b1010'
6 十转八
将 十进制 转换为 八进制
>>> oct(10)
'0o12'
7 十转十六
将 十进制 转换为 十六进制
>>> hex(15)
'0xf'
8 判断是真是假
测试一个对象是True, 还是False
# 当数组为空时,其值为假
>>> bool([])
False
>>> bool([0])
>True
>>>> bool([1])
>True
9 字符串转字节
将一个 字符串 转换成 字节 类型
>>> s = 'apple'
>>> bytes(s,encoding='utf-8')
b'apple'
10 转为字符串
将 字符类型 、 数值类型 等转换为 字符串 类型
>>> i = 100
>>> str(i)
'100'
11 是否可调用
判断对象是否可被调用,能被调用的对象就是一个callable对象,比如函数str, int等都是可被调用的,但是例子4中xiaoming实例是不可被调用的:
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
if __name__ == '__main__':
Xiaoming = Student(1, '小明')
print(callable(int))
print(callable(str))
print(callable(Xiaoming))
True
True
False
如果想让xiaoming能被调用 xiaoming(), 需要重写Student类的__call__方法:
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
def __call__(self, *args, **kwargs):
print('I can be called')
print('My name is 小明')
if __name__ == '__main__':
Xiaoming = Student(1, '小明')
print(callable(int))
print(callable(str))
print(callable(Xiaoming))
Xiaoming()
True
True
True
I can be called
My name is 小明
12 十转ASCII
查看十进制整数对应的ASCII字符
>>> chr(65)
'A'
13 ASCII转十
查看某个ASCII字符对应的十进制数
>>> ord('A')
65
14 类方法
classmethod装饰器对应的函数不需要实例化,不需要self参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
@classmethod
def cm(cls):
print(cls)
if __name__ == '__main__':
Xiaoming = Student(1, '小明')
Xiaoming.cm()
<class '__main__.Student'>
15 执行字符串表示的代码
将字符串编译成python能识别或可执行的代码,也可以将文字读成字符串再编译。
def main1():
s = 'print("Hello!World1!")'
r = compile(s, '<string>', 'exec')
exec(r)
def main2():
s = 'print("Hello!World2!")'
eval(s)
if __name__ == '__main__':
main1()
main2()
Hello!World1!
Hello!World2!
16 创建复数
创建一个复数
>>> complex(1,2)
(1+2j)
17 动态删除属性
删除对象的属性
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
if __name__ == '__main__':
xiaoming = Student(1, '小明')
# 查看对象是否存在此属性
print(hasattr(xiaoming, 'id'))
# 动态删除此属性
delattr(xiaoming, 'id')
print(hasattr(xiaoming, 'id'))
True
False
18 转为字典
创建数据字典
>>> 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}
19 一键查看对象所有方法
不带参数时返回当前范围内的变量、方法和定义的类型列表;带参数时返回参数的属性,方法列表。
>>> dir(xiaoming)
['__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__','name']
20 取商和余数
分别取商和余数
>>> divmod(10,3)
(3, 1)
21枚举对象
返回一个可以枚举的对象,该对象的next()方法将返回一个元组。
myList = ['a', 'b', 'c','d']
for i, v in enumerate(myList, 1):
print(i, v)
2 a
3 b
4 c
5 d
22 计算表达式
将字符串str 当成有效的表达式来求值并返回计算结果取出字符串中内容
>>> s = "1 + 3 +5"
>>> eval(s)
9
23 查看变量所占字节数
>>> import sys
>>> a = {'a':1,'b':2.0}
>>> sys.getsizeof(a)
240
# 占用240个字节
24 过滤器
在函数中设定过滤条件,迭代元素,保留返回值为True的元素:
>>> fil = filter(lambda x: x>10,)
25 转为浮点类型
将一个整数或数值型字符串转换为浮点数
>>> float(3)
3.0
如果不能转化为浮点数,则会报ValueError
26 字符串格式化
格式化输出字符串,format(value, format_spec)实质上是调用了value的format(format_spec)方法。
>>> print('i am {0},age{i}'.format('tom',18))
i am tom,age 18
数值 |
表达式 |
输出结果 |
说明 |
3.1415926 |
{:.2f} |
3.14 |
保留小数点后两位 |
3.1415926 |
{:+.2f} |
+3.14 |
带符号保留小数点后两位 |
-1 |
{:+.2f} |
-1.00 |
带符号保留小数点后两位 |
2.71828 |
{:.0f} |
3 |
不带小数(四舍五入) |
5 |
{:0>2d} |
05 |
数字补零 (右对齐,0填充左边, 宽度为2) |
5 |
{:x<4d} |
5xxx |
数字补x (左对齐,x填充右边, 宽度为4) |
1000000 |
{:,} |
1,000,000 |
以逗号分隔的数字格式 |
0.25 |
{:.2%} |
25.00% |
百分比格式 |
1000000 |
{:.2e} |
1.00e+06 |
指数记法 |
18 |
{:>10d} |
’ 18’ |
右对齐 (默认, 宽度为10) |
18 |
{:<10d} |
'18 ’ |
左对齐 (宽度为10) |
18 |
{:^10d} |
’ 18 ’ |
中间对齐 |
27 冻结集合
创建一个不可修改的集合
>>> frozenset([1,2,3])
因为不可修改,所以没有像set那样的add和pop方法
28 动态获取对象属性
获取对象的属性
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
if __name__ == '__main__':
xiaoming = Student(1, '小明')
print(getattr(xiaoming, 'name'))
小明
29 对象是否有这个属性
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
if __name__ == '__main__':
xiaoming = Student(1, '小明')
print(hasattr(xiaoming, 'name'))
print(hasattr(xiaoming, 'age'))
True
False
30 返回对象的哈希值
返回对象的哈希值,值得注意的是自定义的实例都是可哈希的,list, dict, set等可变对象都是不可哈希的(unhashable)
class Student:
def __init__(self, id, name):
self.id = id
self.name = name
def __repr__(self):
return f'id={self.id},name={self.name}'
if __name__ == '__main__':
xiaoming = Student(1, '小明')
print(hash(xiaoming))
1133299
31 一键帮助
返回对象的帮助文档
>>> help(xiaoming)
Help on Student in module __main__ object:
class Student(builtins.object)
| Student(id, name)
|
| Methods defined here:
|
| __init__(self, id, name)
| Initialize self. See help(type(self)) for accurate signature.
|
| __repr__(self)
| Return repr(self).
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
None
32 对象门牌号
返回对象内存地址
>>> id(xiaoming)
98234208
33 获取用户输入
获取用户输入内容
>>> input()
hello
'hello'
34 转为整型
int(x, base =10) , x可能为字符串或数值,将x 转换为一个普通整数。如果参数是字符串,那么它可能包含符号和小数点。如果超出了普通整数的表示范围,一个长整数被返回。
>>> int('100')
100
# 将字符串的数看做2进制
>>> int('100',2)
4
35 isinstance
判断object是否为类classinfo的实例,是返回true
>>> isinstance(xiaoming,Student)
True
父子关系鉴定
>>> classundergraduate(Student):
>>> defstudyClass(self):
>>> pass
>>> defattendActivity(self):
>>> pass
>>> issubclass(undergraduate,Student)
True
>>> issubclass(object,Student)
False
>>> issubclass(Student,object)
True
如果class是classinfo元组中某个元素的子类,也会返回True
>>> issubclass(int,(int,float))
True
37 创建迭代器类型
使用iter(obj, sentinel), 返回一个可迭代对象, sentinel可省略(一旦迭代到此元素,立即终止)
def main():
lst = [1, 2, 3, 4]
for i in iter(lst):
print(i)
class TseIter:
def __init__(self):
self.l = [1, 2, 3, 4, 5]
self.i = iter(self.l)
def __call__(self, *args, **kwargs):
item = next(self.i)
print('__call__ is called,next iter is', item)
return item
def __iter__(self):
print('__iter__ is called:')
return iter(self.l)
if __name__ == '__main__':
main()
t = TseIter()
t() # 因为实现了__call__可以直接调用
t()
t()
for e in TseIter(): # 因为实现了__iter__方法,所以t能被迭代
print(e)
1
2
3
4
__call__ is called,next iter is 1
__call__ is called,next iter is 2
__call__ is called,next iter is 3
__iter__ is called:
1
2
3
4
5
38 所有对象之根
object 是所有类的基类
>>> o = object()
>>> type(o)
object
39 打开文件
返回文件对象
f = open(r'39.txt', 'r', encoding='utf-8')
print(f.read())
f.close()
hello!world!
mode取值表:
字符 |
意义 |
‘r’ |
读取(默认) |
‘w’ |
写入,并先截断文件 |
‘x’ |
排它性创建,如果文件已存在则失败 |
‘a’ |
写入,如果文件存在则在末尾追加 |
‘b’ |
二进制模式 |
‘t’ |
文本模式(默认) |
‘+’ |
打开用于更新(读取与写入) |
40 次幂
base为底的exp次幂,如果mod给出,取余
# 2**3
>>> pow(3, 2)
9
# 2**3%3
>>> pow(3, 2, 4)
1
41 打印
>>> lst = [1,3,5]
>>> print(lst)
[1, 3, 5]
>>> print(f'lst: {lst}')
lst: [1, 3, 5]
>>> print('lst:{}'.format(lst))
lst:[1, 3, 5]
>>> print('lst:',lst)
lst: [1, 3, 5]
42 创建属性的两种方式
返回 property 属性,典型的用法:
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
# 使用property类创建 property 属性
x = property(getx, setx, delx, "I'm the 'x' property.")
使用python装饰器,实现与上完全一样的效果代码:
class C:
def __init__(self):
self._x = None
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
43 创建range序列
- range(stop)
- range(start, stop[,step])
>>> print(range(11))
range(0,11)
44 反向迭代器
>>> rev = reversed([1,2,3,4])
>>> for i in rev:
>>> print(i)
4
3
2
1
45 四舍五入
四舍五入,ndigits代表小数点后保留几位:
>>> round(10.0252222, 3)
10.025
>>> round(10.0252222, 2)
10.03
46 转为集合类型
返回一个set对象,集合内不允许有重复元素:
>>> a = [1,4,2,3,1]
>>> set(a)
{1, 2, 3, 4}
47 转为切片对象
class slice(start, stop[, step])
返回一个表示由 range(start, stop, step) 所指定索引集的 slice对象,它让代码可读性、可维护性变好。
>>> a = [1,2,3,4,5,6,7,8,9]
>>> slice_meaning = slice(0,6,2)
>>> print(a[slice_meaning])
[1, 3, 5]
48 拿来就用的排序函数
排序:
>>> a = [1,4,2,3,1]
>>> b = sorted(a,reverse=True)
>>> b
[4, 3, 2, 1, 1]
>>> a = [{'name':'xiaoming','age':20,'gender':'male'},{'name':'xiaohong','age':18,'gender':'female'}]
# 根据性年龄排序
>>> b = sorted(a,key=lambda x: x['age'],reverse=False)
>>> b
[{'name': 'xiaohong', 'age': 18, 'gender': 'female'}, {'name': 'xiaoming', 'age': 20, 'gender': 'male'}]
49 求和函数
求和:
>>> a = [1,2,3,4,5]
>>> sum(a)
11
>>> sum(a,10) # 求和的初始值为10
21
50 转元组
tuple() 将对象转为一个不可变的序列类型
>>> my_list = [1,2,3]
>>> tuple(my_list)
(1, 2, 3)
51 查看对象类型
classtype(name, bases, dict)
传入一个参数时,返回object的类型:
>>> type(xiaoming)
__main__.Student
>>> type(tuple())
tuple
52 聚合迭代器
创建一个聚合了来自每个可迭代对象中的元素的迭代器:
>>> x = [1,2,3]
>>> y = [4,5,6]
>>> list(zip(x,y))
[(1, 4), (2, 5), (3, 6)]
>>> a = range(5)
>>> b = list('abcde')
>>> [str(y) + str(x) for x,y in zip(a, b)]
['a0', 'b1', 'c2', 'd3', 'e4']
53 nonlocal用于内嵌函数中
关键词nonlocal常用于函数嵌套中,声明变量i为非局部变量;如果不声明,i+=1表明i为函数wrapper内的局部变量,因为在i+=1引用(reference)时,i未被声明,所以会报unreferencedvariable的错误。
def out_def():
i = 0
j = 0
def in_def():
i = 1
nonlocal j
j = 1
in_def()
print('i=', i)
print('j=', j)
out_def()
i= 0
j= 1
54 global 声明全局变量
先回答为什么要有global,一个变量被多个函数引用,想让全局变量被所有函数共享。
def out_def():
global i
i = 1
print('i=', i)
def in_def():
global i
i = 2
print('i=', i)
in_def()
i = 0
print('i=', i)
out_def()
55 链式比较
i = 3
print(1<i<3) # False
print(1<i<= 3) # True
56 不用else和if实现计算器
from operator import *
def calculator(a, b, k):
return {
'+': add,
'-': sub,
'*': mul,
'/': truediv,
'**': pow
}[k](a, b)
print(calculator(1, 2, '+'))
print(calculator(1, 2, '*'))
print(calculator(2, 3, '**'))
3
2
8
57 链式操作
from operator import (add, sub)
def add_or_sun(a, b, oper):
return (add if oper == '+' else sub)(a, b)
print(add_or_sun(1, 2, '+'))
3
交换元素
def swap(a, b):
return b, a
x = 1
y = 100
x, y = swap(x, y)
print(x, y)
# 或x,y = y,x
100 1
59 去最求平均
def avg(my_list):
# 排序
my_list.sort()
# 去掉最高最低
my_list = my_list[1:len(my_list) - 1]
# 求平均
return sum(my_list)/len(my_list)
myList = [1, 2.3, 45, 2, 34, 12, 15, 13.2, 34, 11]
print(avg(myList))
15.4375
60 打印99乘法表
打印出如下格式的乘法表
for i in range(1, 10):
for j in range(1, i + 1):
print(f'{i:<d} * {j:<d} = {i * j:<2d}', end='\t')
print()
1 * 1 = 1
2 * 1 = 2 2 * 2 = 4
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16
5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25
6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36
7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49
8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64
9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
61 二维转一维数组
from numpy import *
a = array([[1, 2], [3, 4], [5, 6]])
print(a)
print()
print(a.flatten())
[[1 2]
[3 4]
[5 6]]
[1 2 3 4 5 6]
62 列表等分
from math import ceil
def divide(lst, size):
if size <= 0:
return [lst]
return [lst[i * size:(i + 1) * size] for i in range(0, ceil(len(lst) / size))]
myList = [1, 2, 3, 4, 5, 6, 7, 8, 9]
r = divide(myList, 3) # 分为3等份
print(r)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
63 列表压缩
def filter_false(lst):
return list(filter(bool, lst))
r = filter_false([None, 0, False, '', [], 'ok', [1, 2]])
print(r)
['ok', [1, 2]]
64 最长列表
def max_length(*lst):
return max(*lst, key=lambda v: len(v))
myList1 = [1, 2, 3]
myList2 = [2, 3, 4, 5, 6, 7]
myList3 = [1, 2, 3, 4, 5]
r = max_length(myList1, myList2, myList3)
print(r)
[2, 3, 4, 5, 6, 7]
65 求众数
def topl(lst):
return max(lst, default='列表为空', key=lambda v: lst.count(v))
myList = [1, 2, 3, 4, 5, 6, 4, 5, 7, 8, 4, 2, 3, 5, 7, 8, 4, 2, 4, 6, 7, ]
r = topl(myList)
print(r)
4
66 列表最大
def max_list(*lst):
return max(max(*lst, key=lambda v: max(v)))
r = max_list(([2, 3, 4], [4, 5, 6], [3, 2, 1]))
print(r)
6
67 列表查重
def has_duplicates(lst):
return len(lst) == len(set(lst))
x = [1, 2, 3, 4, 5, 6]
y = [1, 2, 3, 4, 5, 6, 5, ]
print(has_duplicates(x))
print(has_duplicates(y))
True
False
68 列表翻转
def reverse(lst):
return lst[::-1]
myList1 = [1, 2, 3, 4, 5, 6]
myList2 = [7, 8, 9, 10, 11]
myList2.sort(reverse=True)
print(reverse(myList1))
print(myList2)
[6, 5, 4, 3, 2, 1]
[11, 10, 9, 8, 7]
69 浮点数等差数列
def rang(start, stop, n):
start, stop, n = float('%.2f' % start), float('%.2f' % stop), float('%d' % n)
step = (stop - start) / n
lst = [start]
while n > 0:
start, n = start + step, n - 1
lst.append((round((start), 2)))
return lst
print(rang(1, 9, 10))
[1.0, 1.8, 2.6, 3.4, 4.2, 5.0, 5.8, 6.6, 7.4, 8.2, 9.0]
70 按条件分组
def bif_by(lst, f):
return [[x for x in lst if f(x)], [x for x in lst if not f(x)]]
records = [25, 89, 31, 34, 89, 100, 80, 34, 68]
print(bif_by(records, lambda x: x < 80))
[[25, 31, 34, 34, 68], [89, 89, 100, 80]]
71 map实现向量运算
#多序列运算函数—map(function,iterabel,iterable2)
lst1=[1,2,3,4,5,6]
lst2=[3,4,5,6,3,2]
list(map(lambdax,y:x*y+1,lst1,lst2))
### [4, 9, 16, 25, 16, 13]
72 值最大的字典
def max_pairs(dic):
if len(dic) == 0:
return dic
max_val = max(map(lambda v: v[1], dic.items()))
return [item for item in dic.items() if item[1] == max_val]
r = max_pairs({'a': -10, 'b': 5, 'c': 3, 'd': 5})
print(r) # [('b', 5), ('d', 5)]
73 合并两个字典
def merge_dic(dict1, dict2):
return {**dict1, **dict2}
dic1 = {'a': 1, 'b': 2}
dic2 = {'c': 3}
print(merge_dic(dic1, dic2))
# {'a': 1, 'b': 2, 'c': 3}
dic1.update(dic2)
print(dic1)
# {'a': 1, 'b': 2, 'c': 3}
74 topn 字典
from heapq import nlargest
# 返回字典d前n个最大值对应的键
def topn_dict(d, n):
return nlargest(n, d, key=lambda k: d[k])
topn_dict({'a': 10, 'b': 8, 'c': 9, 'd': 10}, 3)
# ['a', 'd', 'c']
75 异位词
from collections import Counter
# 检查两个字符串是否相同字母异序词,简称:互为变位词
def anagram(str1, str2):
return Counter(str1) == Counter(str2)
anagram('eleven+two', 'twelve+one') # True 这是一对神器的变位词
anagram('eleven', 'twelve') # False
逻辑上合并字典
(1)两种合并字典方法这是一般的字典合并写法
dic1 = {'x': 1, 'y': 2 }
dic2 = {'y': 3, 'z': 4 }
merged1 = {**dic1, **dic2}
# {'x': 1, 'y': 3, 'z': 4}
修改merged[‘x’]=10,dic1中的x值不变,merged是重新生成的一个新字典。
(2)但是,ChainMap却不同,它在内部创建了一个容纳这些字典的列表。因此使用ChainMap合并字典,修改merged[‘x’]=10后,dic1中的x值改变,如下所示:
from collections import ChainMap
merged2 = ChainMap(dic1,dic2)
print(merged2)
# ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4})
77 命名元组提高可读性
from collections import namedtuple
point = namedtuple('point', ['x', 'y']) # 定义名为point的元组,字段属性有x,y
lst = [point(1, 2), point(-1, -2), point(0, 0)]
print(lst[0].x - lst[1].x)
# 2
78 样本抽样
使用sample抽样,如下例子从100个样本中随机抽样10个。
from random import randint, sample
# 生成100个0-50的随机整数
lst = [randint(0, 50) for _ in range(100)]
# 随机抽样10个数
lst_sample = sample(lst, 10)
print(lst_sample)
# [43, 28, 46, 2, 32, 6, 20, 4, 17, 2]
79 重洗数据集
使用shuffle用来重洗数据集,值得注意shuffle是对lst就地(in place)洗牌,节省存储空间
from random import shuffle, randint
lst = [randint(0, 50) for _ in range(10)]
print(lst)
# [40, 3, 14, 9, 2, 10, 50, 26, 23, 24]
shuffle(lst)
print(lst)
# [50, 23, 26, 3, 9, 10, 2, 40, 24, 14]
80 10个均匀分布的坐标点
random模块中的uniform(a,b)生成[a,b)内的一个随机数,如下生成10个均匀分布的二维坐标点
from random import uniform
# 生成5个x,y都是0-10的坐标
lst = [(uniform(0, 10), uniform(0, 10)) for _ in range(5)]
print(lst)
# [(7.701427108117793, 3.843003615554367), (9.71150124517058, 2.090424005828091), (3.915291689286997, 4.616035628641485), (3.582206422891745, 9.19287429253042), (6.079509418205635, 1.9340874788475404)]
81 10个高斯分布的坐标点
random模块中的gauss(u,sigma)生成均值为u, 标准差为sigma的满足高斯分布的值,如下生成10个二维坐标点,样本误差(y-2*x-1)满足均值为0,标准差为1的高斯分布:
from random import gauss
x = range(10)
y = [2 * xi + 1 + gauss(0, 1) for xi in x]
points = list(zip(x, y))
print(points)
# [(0, 0.417218685529018), (1, 4.243458247551363), (2, 4.473432148883277), (3, 7.118490124237332), (4, 8.932064430583193), (5, 11.984077173427817), (6, 12.618979691200993), (7, 14.78533743861569), (8, 15.752137963359067), (9, 17.244251639215747)]
82 chain高效串联多个容器对象
chain函数串联a和b,兼顾内存效率同时写法更加优雅。
from itertools import chain
a = [1, 3, 5, 0]
b = (2, 4, 6)
lst = list(chain(a, b))
print(lst)
# [1, 3, 5, 0, 2, 4, 6]
83 操作函数对象
def f():
print('i am f')
def g():
print('i am g')
[f, g][1]()
# i am g
创建函数对象的list,根据想要调用的index,方便统一调用。
84 生成逆序序列
list(range(10,-1,-1)) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
第三个参数为负时,表示从第一个参数开始递减,终止到第二个参数(不包括此边界)
85 函数的五类参数使用例子
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)。
# 如果要强制使用f(a=1),需要在前面添加一个星号:
def g(*, a):
print(f'a:{a}')
# 此时必须使用f(a=1)调用方法
g(a=1)
# a:1
86 使用slice对象
使用同一种切法[1:10:2]对蛋糕cake1与cake2进行切割:
from random import randint
cake1 = list(range(5, 0, -1))
# cake1=[5, 4, 3, 2, 1]
b = cake1[1:10:2]
# 切得蛋糕b=[4, 2]
cake2 = list(range(1, 11))
# cake2=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
d = cake2[1:10:2]
# 切得蛋糕d=[2, 4, 6, 8, 10]
这里可以将切法定义成slice对象,从而避免繁琐的操作:
cake_slice = slice(1, 10, 2)
cake1 = list(range(5, 0, -1))
cake2 = list(range(1, 11))
print(cake1[cake_slice])
print(cake2[cake_slice])
# [4, 2]
# [2, 4, 6, 8, 10]
87 lambda 函数
# 排序
dic = {'a': 3, 'b': 2, 'c': 1}
print(sorted(dic.items(), key=lambda item: item[1]))
# [('c', 1), ('b', 2), ('a', 3)]
# 求长列表
lsts = [[1, 2, 3], [1, 2], [2, 3, 4, 5]]
print(max(lsts, key=lambda l: len(l)))
# [2, 3, 4, 5]
88 粘性之禅
七行烧脑代码:
def product(*args, repeat=1):
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x + [y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
rtn = product('xyz', '12', repeat=3)
print(list(rtn))
89 元类
xiaoming, xiaohong, xiaozhang都是学生,这类群体叫做Student.
Python 定义类的常见方法,使用关键字class。
class Student():
pass
xiaoming, xiaohong, xiaozhang是类的实例,则:
xiaoming = Student()
xiaohong = Student()
xiaozhang = Student()
创建后,xiaoming 的__class__属性,返回的便是Student类:
xiaoming.__class__
__main__.Student
问题在于,Student类有__class__属性,如果有,返回的又是什么?
xiaoming.__class__.__class__
type
返回type。
那么,我们不妨猜测:Student类,类型就是type。
换句话说,Student类就是一个对象,它的类型就是type。
所以,Python 中一切皆对象,类也是对象。
Python 中,将描述Student类的类被称为:元类。
既然Student类可创建实例,那么type类可创建实例吗?如果能,它创建的实例就叫:类了。
Student = type('Student',(),{})
Student
__main__.Student
它与使用class关键字创建的Student类一模一样。
元类,确实使用不是那么多,也许先了解这些,就能应付一些场合。就连 Python 界的领袖TimPeters都说:
“元类就是深度的魔法,99%的用户应该根本不必为此操心。”
90 对象序列化
对象序列化,是指将内存中的对象转化为可存储或传输的过程。很多场景,直接一个类对象,传输不方便。
但是,当对象序列化后,就会更加方便,因为约定俗成的,接口间的调用或者发起的 web 请求,一般使用 json 串传输。
实际使用中,一般对类对象序列化。先创建一个 Student 类型,并创建两个实例。
class Student():
def __init__(self, **args):
self.ids = ['ids']
self.name = args['name']
self.address = args['address']
xiaoming = Student(ids=1, name='xiaoming', address='北京')
xiaohong = Student(ids=2, name='xiaohong', address='南京')
导入 json 模块,调用 dump 方法,就会将列表对象 [xiaoming,xiaohong],序列化到文件 json.txt中。
import json
with open('90json.txt', 'w') as f:
json.dump([xiaoming, xiaohong], f, default=lambda obj: obj.__dict__, ensure_ascii=False, indent=2, sort_keys=True)
生成文件内容:
[
{
"address": "北京",
"ids": [
"ids"
],
"name": "xiaoming"
},
{
"address": "南京",
"ids": [
"ids"
],
"name": "xiaohong"
}
]