异想家Python学习代码
本文是自己学习廖雪峰Python教程的笔记,记录些常用用法,方便以后找代码片段。
JfzPylib.py文件:
#!/usr/bin/env python3
#coding=utf-8
'''
异想家Python函数库
'''
import math
# 求绝对值
def Fun_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x>=0:
return x
else:
return -x
# 解一元二次方程
def Fun_Solve2yuanEquation(a,b,c):
delta = b*b-4*a*c
if delta < 0:
return
elif delta == 0:
x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
return x1
else:
x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
x2 = (-b - math.sqrt(b*b-4*a*c))/(2*a)
return x1,x2
JfzPyStudy.py文件:
#!/usr/bin/env python3
# coding=utf-8
' 异想家Python学习 '
__author__ = 'Sandeepin'
# 【1】输出
print('\n\033[1;31m【1】输出\033[0m\n')
print("异想家") # 双引号
print('Fuck''Bitch','Shit') # 单引号,逗号间隔,输出变空格
print('1234 - 5678 =',1234-5678) # 输出数字计算
# 【2】输入
print('\n\033[1;31m【2】输入\033[0m\n')
#name = input()
#print(name)
#name2 = input('输入网名')
#print(name2)
# 【3】Python基础
print('\n\033[1;31m【3】Python基础\033[0m\n')
# 缩进强迫写出格式化代码,坚持使用【4个空格】的缩进
# Python程序【大小写敏感】
# 【4】数据类型、变量
print('\n\033[1;31m【4】数据类型、变量\033[0m\n')
print(1024)
print(0xff)
print(1.23e9)
print('abc')
print("xyz")
print("x\'y\'z\n") # 转义字符\n换行
print(r'\\\t\\') # r表示内部字符不转义
print('''123
456
789''') # '''括起的内容可多行
# True False and or not # 布尔运算
# None # 空值
a = 123 # 变量数值
print(a)
a = 'jfz' # 变量字符串,同一变量反复赋值
b = a
a = '666'
print(a)
print(b)
PI = 3.14159265359 # 常量用大写表示,实际上是变量,想改就改
print(PI)
print(10 / 3)
print(10 // 3) # 地板除,整数部分
print(10 % 3) # 余数部分
# Python整数无大小限制,浮点数也没限制,太大会变成inf(无限大)
# ASCII 1个字节,Unicode 通常2个字节, UTF-8 可变长编码(英语1个,中文3个,特殊4-6个)
print('中文str') # python字符串以Unicode编码
print(ord('A')) # ord获取字符整数表示
print(ord('蒋'))
print(chr(66)) # ord编码整数转字符
print(chr(26041))
print('\u4e2d\u6587') # 用16进制写中文
print(b'ABC')# 编码为bytes
print('ABC'.encode('ascii'))
print('异想家123'.encode('utf-8'))
print(b'fuck'.decode('ascii'))# 解码为str
print(b'\xe8\x92\x8b\xe6\x96\xb9\xe6\xad\xa3'.decode('utf-8'))
print(len('ABC')) # 计算str字符数
print(len('异想'))
print(len(b'ABCddd')) # 计算bytes字节数
# 【5】格式化输出
print('\n\033[1;31m【5】格式化输出\033[0m\n')
# 和C语言类似,%d %f %s %x
print('Jfz %d poi %s' %(77, 'sandeepin') ) # 几个%号,在后面就用%(1,2)填几个
print('%02d %07.3f' %(7, 33.3333333333) ) # 补零,类似C语言
print('年龄: %s %% 男士: %s' %(23, True) ) # %s永远起作用,不知道用什么的时候用它, %%转义%
s1 = 72
s2 = 85
r = s1/s2
print('比率s1/s2 = %.2f' % r)
print('彩色显示:\033[1;31mSandeepin\033[0m')
# 【6】list列表
print('\n\033[1;31m【6】list列表\033[0m\n')
# list列表是可变有序集合,用xxx = ['1','2','3']表示
classmates = ['Sandeepin', 'Samothrace', 'Bitch']
print(classmates)
print(len(classmates)) # list元素个数
print(classmates[0]) # 类似数组下标的方式访问元素,从0开始
print(classmates[2])
print(classmates[-1]) # 倒数第一个,即classmates[2]
print(classmates[-2]) # 倒数第二个
classmates.append('Jfz') # 追加元素
classmates.insert(1,'poi') # 插入元素,插在第1个(下标从0开始)
print(classmates)
classmates.pop() # 弹出,最后一个元素删除
print(classmates)
classmates.pop(2) # 弹出下标为2的那个
print(classmates)
classmates[0] = 'jiangfangzheng' # 替换用赋值方法
print(classmates)
mixlist = ['poi',123,3.5678,['www','jj']] # list元素类型可混合,list套list
print(mixlist[3][1]) # 相当于二维数组
nonelist=[]
print(len(nonelist)) # 空list
# 【7】tuple元组
print('\n\033[1;31m【7】tuple元组\033[0m\n')
# tuple元组是有序列表,类似list,但是tuple初始化后不能改,用xxx = ('1','2','3')表示
classmates = ('Michael', 'Bob', 'Tracy')
print(classmates)
print(classmates[1])
t = (1,) # 只有一个元素的tuple要加个逗号,避免歧义为赋值1
print(t) # 显示时也会加逗号防止误解
t = ('a', 'b', ['A', 'B'])
t[2][0] = 'X'
print(t) # tuple元素不变,里面有list,list元素可变
# 【8】条件判断
print('\n\033[1;31m【8】条件判断\033[0m\n')
age = 19
if age >= 18:
print('成年人') # 从上往下判断,符合要求后剩下的判断忽略
elif age>=6:
print('青少年')
else:
print('小孩')
x =3
if x:
print('True') # 简写,x非0,非空就为True
#year = input()
##if year > 2000: # 输入1999程序出错,因为输入的是字符串,要转成整数
#if int(year) > 2000: # int()函数转整数
# print('2000年之后')
#else:
# print('2000年之前')
#print('体重判断程序')
#height = input('输入身高')
#weight = input('输入体重')
#bmi = int(weight)/(int(height)*int(height))
#if bmi>25:
# pass # pass跳过,不填报错
#else:
# print('不胖')
# 【9】循坏
print('\n\033[1;31m【9】循坏\033[0m\n')
# 第1种 for...in循坏
names = ['异想家','sandeepin','jfz']
for aaa in names: # 就是把每个元素带入aaa,执行下面语句一回
print(aaa)
# 求和举例
qiuhe = 0
for x in [1,2,3,4,5,6,7,8,9,10]:
qiuhe = qiuhe + x
print(qiuhe)
qiuhe = 0
for x in range(11): # 生成从0开始的小于11的数的list
qiuhe = qiuhe + x
print(qiuhe)
# 第2种 while循坏
n = 10
qiuhe = 0
while n > 0:
qiuhe = qiuhe + n
n = n -1
print(qiuhe)
# 【技巧】死循环时按Ctrl + C 强制退出
# 【10】字典
print('\n\033[1;31m【10】字典\033[0m\n')
# 字典dictionary类似其它语言中的map,键-值存储,快速查找,其内部存放顺序与放入顺序无关
# 字典以空间(内存)换时间,list以时间换空间,dictionary适合高速场合
# 字典的Key不能变,因此不能以list作为Key
jfzn = {'jfz':100,'sandeepin':96,'poi':88}
print(jfzn['poi']) # 就像给数组的下标起别名,访问对应数值
jfzn['jfz'] = 99 # 字典内容赋值
print(jfzn['jfz'])
print('Thomas' in jfzn) # 判断Key是否在字典中
print(jfzn.get('Thomas')) # 不在返回None
print(jfzn.get('Thomas', 999)) # 不在返回自定义的999
print(jfzn.pop('poi')) # 弹出Key
print(jfzn)
# set类似字典dict,是Key的集合,可作交并计算,不储存value
s = set([1, 2, 3]) # list作为输入
ss = set([1,1,2,2,3,3]) # 滤除重复元素
print(s)
s.add(4) # 添加Key,重复无用
s.remove(1) # 移除Key
print(s)
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
print(s1 & s2) # 交运算
print(s1 | s2)
# 【11】可变与不可变学习
print('\n\033[1;31m【11】可变与不可变学习\033[0m\n')
# list可变
abc = ['b','a','c']
abc.sort() # 排序
print(abc)
# str不可变
strabc = 'bac'
print(strabc.replace('b','B')) # 替换只对当前有效,strabc本质没变
print(strabc)
# 【12】函数
print('\n\033[1;31m【12】函数\033[0m\n')
# 调用函数 help(abs) 查看abs函数信息,官网看文档 http://docs.python.org/3/library/functions.html#abs
print(abs(-5))
print(max(2, 3, 1, -5))
# 数据类型转换函数
print(int('123'))
print(int(12.3))
print(float(123.456))
print(bool(1))
# 函数名本身就是一个引用,完全可以给函数名取别名
ShiLiu = hex
print(ShiLiu(12))
# 自定义函数
def Fun_SanCiFang(x):
return x*x*x
print(Fun_SanCiFang(3)) # 调用函数
from JfzPylib import Fun_abs # 从JfzPylib.py文件中导入函数Fun_abs
print(Fun_abs(-93))
# 返回多个值
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
print(move(10, 20, 50)) # 返回的本质是一个元组
x, y = move(10, 20, 50) # 返回一个元组可省略括号
print(x, y)
def Fun_Solve2yuanEquation(a,b,c): # 解二次方程函数
delta = b*b-4*a*c
if delta < 0:
return
elif delta == 0:
x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
return x1
else:
x1 = (-b + math.sqrt(b*b-4*a*c))/(2*a)
x2 = (-b - math.sqrt(b*b-4*a*c))/(2*a)
return x1,x2
print(Fun_Solve2yuanEquation(1,4,7774))
# 函数参数——默认参数、可变参数、关键字参数
def CiFang(x):
return x*x
print(CiFang(2))
def LiFang(x):
return x*x*x
print(LiFang(2))
# 位置参数,顺序要定好,n=2是默认参数
def CiFangN(x, n=2):
out = 1
while n > 0:
out = out * x
n = n - 1
return out
print(CiFangN(2,4))# 位置参数
print(CiFangN(2)) # 默认参数,必选参数在前,默认参数在后,否则有歧义
# 默认参数,变化大的放在前面,变化小的放在后面
def ZhuCe(name, gender , age=6, city = 'Guilin'):
print('name=%s, gender=%d, age=%d, city=%s'%(name,gender,age,city))
return 'OK'
print(ZhuCe('jfz', 2))
print(ZhuCe('poi', 1, 8)) # 按顺序补全
print(ZhuCe('poi', 1, city='wuhan')) # 选择输入city,其它默认
# 一个坑
def add_end(L=[]):
L.append('END')
return L
poid=[3,2,1]
print(add_end(poid))
print(add_end())
print(add_end()) # 输出了['END', 'END'],默认参数L被记着了,不能这么用
# 正确写法:
def add_endfix(L=None):
if L is None:
L=[]
else:
L.append('END')
return L
print(add_endfix())
print(add_end())
# 【技巧】能设计为不变对象时,就尽量设计成不变对象,防止意外修改
# 可变参数——传入的参数可变
# 传统方法:传list或tuple
def calcX2(shuru):
sum = 0
for fuck in shuru:
sum = fuck*fuck +sum
return sum
fuckk=[1,2,3]
print('calcX2 =',calcX2(fuckk))
# 可变参数法——仅在参数前加个*号
def calcX2B(*shuru):
sum = 0
for fuck in shuru:
sum = fuck*fuck +sum
return sum
print('calcX2B =',calcX2B(fuckk[0], fuckk[1], fuckk[2])) # 输入参方法1
print('calcX2B =',calcX2B(*fuckk)) # 输入参方法2
print('calcX2B =',calcX2B(1, 2, 3)) # 输入参方法3
# 关键字参数——加两个**,扩展函数功能,获得额外信息
def ZhuCeKW(name, gender , **kw):
print('name=%s, gender=%d other='%(name, gender), kw)
return 'OK'
print(ZhuCeKW('duck', 3))
print(ZhuCeKW('duck', 3, city='wuhan'))
extra = {'age':12, 'city':'guilin'} # 键值形式输入
print(ZhuCeKW('duck', 3, **extra)) # extra加**
# 限制关键字参数——命名关键字参数
# 例如只接受city和age
# 命名关键字参数以特殊的单个*表示,后面的为命名关键字参数
# 命名关键字参数必须传入参数名
def ZhuCeCheck(name, gender, *, age, city='guilin'):
print(name, gender, age, city)
return 'OK'
print(ZhuCeCheck('Jack', 24, city='Beijing', age = 11))
# print(ZhuCeCheck('Jack', 24, city='Beijing', job='Engineer')) # 输出出错
# 参数组合举例——必选、默认、可变、关键字、命名关键字
# 顺序: 必选、默认、可变\关键字\命名关键字
# 可变和命名显然不能混在一起
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
f1(1, 2)
f1(1, 2, c=3)
f1(1, 2, 3, 'a', 'b') # a、b是可变
f1(1, 2, 3, 'a', 'b', x=99) # x=99是关键字,用 = 表示键值配对
f2(1, 2, d=99, ext=None) # d为命名关键字,只有写d=xx才对,**kw就换成关键字了,变成键值配对
args = (1, 2, 3, 4) # 通过tuple和dict作为输入
kw = {'d': 99, 'x': '#'}
f1(*args, **kw) # 任意函数都可以以形式f1(*args, **kw)调用
args = (1, 2, 3)
kw = {'d': 88, 'x': '#'}
f2(*args, **kw)
# 【小结】
# *args是可变参数,接收tuple元组
# **kw是关键字参数,接收dict字典
# func(1,2,3)可以装list、tuple通过*args传入func(*(1,2,3))
# func(a=1,b=2),可以装dict通过**kw传入func(**{'a':1,'b':2})
# 【13】递归函数——函数调用本身
print('\n\033[1;31m【13】递归函数\033[0m\n')
def JieCheng(n):
if n == 1:
return 1
else:
return n * JieCheng(n-1)
print('递归阶乘:', JieCheng(5))
# 递归太多层会栈溢出,解决方法:尾递归优化
# 常规递归过程如下:
# ===> fact(5)
# ===> 5 * fact(4)
# ===> 5 * (4 * fact(3))
# ===> 5 * (4 * (3 * fact(2)))
# ===> 5 * (4 * (3 * (2 * fact(1))))
# ===> 5 * (4 * (3 * (2 * 1)))
# ===> 5 * (4 * (3 * 2))
# ===> 5 * (4 * 6)
# ===> 5 * 24
# ===> 120
def fact(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
print('优化阶乘:', fact(5))
# 优化递归过程如下:
# ===> fact_iter(5, 1)
# ===> fact_iter(4, 5)
# ===> fact_iter(3, 20)
# ===> fact_iter(2, 60)
# ===> fact_iter(1, 120)
# ===> 120
# 【遗憾的是】python没对尾递归优化,这样写照样爆栈
# 利用递归函数移动汉诺塔:
def move(n, a, b, c):
if n == 1:
print('move', a, '-->', c)
return
move(n-1, a, c, b)
print('move', a, '-->', c)
move(n-1, b, a, c)
move(3, 'A', 'B', 'C') # n为A盘数量1
# 【14】高级特性
print('\n\033[1;31m【14】高级特性\033[0m\n')
# 传统的循坏实现 1 3 5 7 9
L = []
n = 1
while n <= 99:
L.append(n)
n = n + 2
print(L)
print('\n【1、切片Slice】')
# 切片Slice
L = ['Fuck','Bitch','Shit','Porn']
LL = [L[0],L[1],L[2]] # 笨办法
print(LL)
LL = []
for n in range(2): # 循环办法
LL.append(L[n])
print(LL)
LLL = L[0:3] # 切片办法,代表取0 1 2号元素
LLL = L[:3] # 切片办法,0开始取可省略0
LLL = L[1:4] # 切片办法,1 2 3
LLL = L[-2:-1] # 切片办法,取倒数第二个2到倒数第1个(不包括倒数第1个)
LLL = L[-2:] # 包括倒数第1个
print(LLL)
# 各种取法
L = list(range(100))
print(L)
LL = L[:10]
print(LL)
LL = L[-10:]
print(LL)
LL = L[0:10:2] # 取0~10,隔2-1=1个取一个(第一个必取,从第一个开始,2个中取一个)
print(LL)
LL = L[::5] # 全取,每5个取一个
print(LL)
LL = L[:] # 全取,等于复制
print(LL)
T = (1,2,3,4,5)
TT = T[2:4] # Tuple也可切片(1,2,3)[:3]类似形式
print(TT)
Str1 = 'abcdefg'
Str2 = Str1[0:3] # 字符串也可切片
print(Str2)
# 【总结】切片可以节省循环,一句话实现
# 【迭代Iteration】
print('\n【2、迭代Iteration】')
# for循环遍历一遍就是迭代
# Python的for是高度抽象的循环
Fuck = {'Bitch':'Good','Porn':'OK','Shit':'No'}
for key in Fuck: # 默认迭代key
print(key)
for value in Fuck.values(): # 迭代value
print(value)
for item in Fuck.items(): # 迭代key和value
print(item)
for ch in 'Sandeepin': # 字符串迭代
print(ch)
# 判断一个对象是否能迭代
from collections import Iterable
print(isinstance('abc', Iterable)) # str可以
print(isinstance(123, Iterable)) # 整数不行
# 对list实现类似Java的下标循环
for i, value in enumerate(['A', 'B', 'C']):
print(i,value)
for x, y in [(1, 1), (2, 4), (3, 9)]: # 实现for循环引用两个变量
print(x, y)
# 【列表生成式List Comprehensions】
print('\n【3、列表生成式List Comprehensions】')
# 用来创建list的生成式
# 生成 1 2 3 ... 10
print(list(range(1, 11)))
L = []
# 生成 1 4 9 ... 100
for x in range(1, 11):
L.append(x * x)
print(L)
# 列表生成式的方法,生成 1 4 9 ... 100
LLL = [x * x for x in range(1, 11)] # 生成结果 for 序号 in 序列
print(LLL)
# 后面能加 if 条件,例如只生成偶数的平方结果
LLL2 = [x * x for x in range(1, 11) if x%2 is 0] # 生成结果 for 序号 in 序列
print(LLL2)
# 还可以两层、多层循环,实现全排列
LL = [m+n for m in 'ABC' for n in 'xyz']
print(LL)
# 字典键值同时迭代
for key,value in Fuck.items(): # 迭代key和value
print(key,'=',value)
# 利用两个变量生成list
d = {'x': 'A', 'y': 'B', 'z': 'C' }
dd = [k + '=' + v for k, v in d.items()]
# list元素变小写
L = ['Hello', 'World', 'IBM', 'Apple']
L = [s.lower() for s in L]
print(L)
# 列出当前文件夹所有文件和目录
import os # 导入OS模块
dirr = [d for d in os.listdir('.')] # os.listdir列出当前文件夹所有文件和目录
print(dirr)
# 混合整型字符串的list转小写
L = ['Hello', 'World', 18, 'Apple', None]
S = [ss.lower() for ss in L if isinstance(ss, str)] # 判断是否为字符串
print(S)
# 【生成器Generator】
print('\n【4、生成器Generator】')
# 列表生成式生成List受内存限制,很浪费空间。生成器在循环过程中不断推出后续元素,不必创建大量list,节省空间。
# 创建生成器Generator方法1:列表生成式[]改为()
g = (x * x for x in range(10))
print(next(g))
print(next(g))
print(next(g)) # 用next方法打印生成器
for n in g: # 用for打印
print(n)
# 复杂情况for循环实现不了的时候用函数实现,就需要生成器了
# Fibonacci数列 1, 1, 2, 3, 5, 8, 13, 21, 34
def FibonacciNum(num):
n, a, b = 0, 0, 1
while n < num:
print(b)
c = b
b = a + b
a = c
# a, b = b, a + b # 同时进行,可以省去一个变量
n = n + 1
return 'poi'
FibonacciNum(10)
# 递归实现Fibonacci数列
def FibonacciNumDigui(num):
if num == 1:
return 1
elif num == 2:
return 1
else:
out = FibonacciNumDigui(num - 1) + FibonacciNumDigui(num - 2)
return out
print(FibonacciNumDigui(8))
# 变成生成器,只需要把print变成yield
def FibonacciGenerator(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'ppp'
# 变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
fg = FibonacciGenerator(6)
print(next(fg)) # 在执行过程中,遇到yield就中断,下次又继续执行
print(next(fg))
print(next(fg))
print(next(fg))
print(next(fg))
print(next(fg))
for n in FibonacciGenerator(6): # for循坏调用生成器,基本上不用next
print(n) # 但是拿不到return的值,要用StopIteration,以后再说
# 杨辉三角形生成[jfz写,不完善]
def YangTriangles(num):
if num == 1:
a = [1,]
#print(a)
return a
if num == 2:
a = [1,1]
#print(a)
return a
if num >=3:
c = list(range(num))
c[0] = 1
c[-1] = 1
for i in range(1,num-1):
c[i] = YangTriangles(num-1)[i-1] + YangTriangles(num-1)[i]
return c
print(YangTriangles(6))
# 【迭代器Iterable】
print('\n【5、迭代器Iterable】')
# 可以直接作用于for循环的对象统称为可迭代对象:Iterable: list、tuple、dict、set、str、generator
# 用isinstance()判断
from collections import Iterable
print('迭代对象:',isinstance((x for x in range(10)), Iterable))
print('迭代对象:',isinstance('1232',Iterable)) # 字符串可以
print('迭代对象:',isinstance(1232,Iterable)) # 数字不可以
# 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
from collections import Iterator
print('迭代器:',isinstance((x for x in range(10)), Iterator))
print('迭代器:',isinstance('1232',Iterator))
# 可迭代对象变迭代器:iter()
print('变迭代器:',isinstance(iter([]), Iterator))
print('变迭代器:',isinstance(iter('1232'),Iterator))
# Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
# 【15】函数式编程
print('\n\033[1;31m【15】函数式编程\033[0m\n')
# Functional Programming,函数式编程就是一种抽象程度很高的编程范式
# 函数式编程的一个特点: 允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
# 【高阶函数Higher-order function】
print('\n【1、高阶函数Higher-order function】')
absxxx = abs(-10) # 变量指向函数返回值
print(absxxx)
absxx = abs # 变量指向函数本身,函数名本身可看作一个变量,它指向具有某种作用的一个函数
print(absxx(-777))
# 一个函数接受另一个函数作为变量
def add(x, y, f):
return f(x) + f(y)
print(add(-2, -3, abs))
# 把函数作为参数传入,这样的函数称为【高阶函数】
#【map/reduce】
# 有一个函数f(x)=x^2,要把这个函数作用在一个list[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现
fuck = [1,2,3,4,5,6]
def square2(x):
return x * x
xxx = map(square2,fuck) # 结果r是一个Iterator惰性序列
print(list(xxx)) # 用list算迭代器,计算出来
print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))) # 将数字字符串化
# reduce把一个函数作用在一个序列[x1, x2, x3, ...]上, 把结果继续和序列的下一个元素做累积计算
# 效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
def add(x, y):
return x + y
print(reduce(add, [1, 2, 3, 4, 5])) # 等于是求和,还可用sum
# 把序列[1, 3, 5, 7, 9]变换成整数13579
def fn(x, y):
return x * 10 + y
print(reduce(fn, [1, 3, 5, 7, 9]))
# map/reduce配合,整理成一个str2int的函数
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
return reduce(fn, map(char2num, s))
print(str2int('123'))
# (jfz)实现输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']
def normalize(name):
namelow = name.lower() # 转小写
return namelow.capitalize() # 转首字母大写
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)
# (jfz)实现类似sum求和的求积函数prod()
def prod(L):
def squareXxY(x, y):
return x * y
return reduce(squareXxY, L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
# (jfz)实现str2float函数
def str2float(instr):
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
return reduce(fn, map(char2num, s))
[z, x]=instr.split('.')
return str2int(z) + str2int(x)/(pow(10, len(x)))
print(str2float('123.456777'))
#【filter】
# filter()函数用于过滤序列
# 和map()类似,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
# 例如删掉偶数
def is_odd(n):
return n % 2 == 1
print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])))
# 例如删掉空字符串
def not_empty(s):
return s and s.strip()
print(list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])))
# 【注意】filter()函数返回的是Iterator,也要list化
# 埃氏筛法用filter求素数
# 先构造一个从3开始的奇数序列:
def _odd_iter():
n = 1
while True:
n = n + 2
yield n
# 定义一个筛选函数:
def _not_divisible(n):
return lambda x: x % n > 0
# 定义一个生成器,不断返回下一个素数:
def primes():
yield 2
it = _odd_iter() # 初始序列
while True:
n = next(it) # 返回序列的第一个数
yield n
it = filter(_not_divisible(n), it) # 构造新序列
# 调用时需要设置一个退出循环的条件:
# 打印1000以内的素数:
for n in primes():
if n < 1000:
print(n)
else:
break
# (jfz)利用filter()滤掉非回文数:
print('回文数:')
def is_palindrome(n):
strn = str(n) # 转字符串
i= len(strn)//2 # 半长度
k = 0 # 回文计数
for j in range(i):
if strn[j] == strn[-(j+1)]:
k = k + 1
if k == i:# 回文次数=半长度说明回文
return True
else:
return False
output = filter(is_palindrome, range(1, 1000))
print(list(output))
#【排序算法sorted】
# 排序的核心是比较两个元素的大小
# 数字直接比较,字符串或者两个dict呢?比较的过程必须通过函数抽象出来。
# 默认从小到大排list
print('从小到大排序:',sorted([36, 5, -12, 9, -21]))
# sorted()函数是高阶函数,可以接收一个key函数来实现自定义的排序
print('绝对值排序:',sorted([36, 5, -12, 9, -21],key=abs))
# 字符串排序,按ASCII的大小比较
print('字符串排序:',sorted(['bob', 'about', 'Zoo', 'Credit']))
# 按照字母序排序,忽略大小写
print('按字母排序(忽略大小写):',sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower))
# 反向排序,只需要传入第三个参数reverse=True
print('反向排序(从大到小):',sorted([36, 5, -12, 9, -21],reverse=True))
# 学生名字和成绩: 按名字排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
tt = t[0]
return tt
L2 = sorted(L, key=by_name)
print('按名字排序:',L2)
# 学生名字和成绩: 按成绩从高到低排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_score(t):
tt = t[1]
return tt
L2 = sorted(L, key=by_score, reverse=True)
print('按成绩排序:',L2)
# 返回函数
print('\n【2、返回函数】')
# 把函数作为结果值返回
# 通常求和的函数
def calc_sum(*args):
ax = 0
for n in args:
ax = ax + n
return a
print('直接求和:',calc_sum(1, 3, 5, 7, 9))
# 如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
# 定义的函数内部再定义一个函数,外函数返回内函数
print('延迟求和(返回求和函数):',lazy_sum(1, 3, 5, 7, 9))
# 当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力
# 当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print('闭包不等:',f1==f2)
# 【闭包】
# 返回的函数并没有立刻执行,而是直到调用了f()才执行
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count() # 将一个list中每个元素分别给f1, f2, f3
print('闭包调用才执行:', f1(), f2(), f3()) # 结果是9 9 9
# 原因就在于返回的函数引用了变量i,但它并非立刻执行。
# 等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9
# 【注意】返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量
# 如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
f1, f2, f3 = count() # 将一个list中每个元素分别给f1, f2, f3
print('多一层函数:', f1(), f2(), f3()) # 结果是1 4 9
# 匿名函数
print('\n【3、匿名函数】')
# 就是没有名字的函数,关键字lambda表示匿名函数,冒号前面的x表示函数参数。
a = list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(a)
# 等于是:
def f(x):
return x * x
a = list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(a)
# 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果
f = lambda x: x * x
print(f(5))
# 把匿名函数作为返回值返回
def build(x, y):
return lambda:x*x+y*y
aaa = build(3, 4)
print(aaa())
# 装饰器
print('\n【4、装饰器】')
# 通过变量也能调用该函数
def jfz():
print('poi')
sa = jfz
sa()
# 函数对象有一个__name__属性,可以拿到函数的名字
print(sa.__name__)
print(jfz.__name__)
# 假设要增强jfz()的功能,如在函数调用前后自动打印日志,但又不希望修改函数
# 这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)
# 本质上,decorator就是一个返回函数的高阶函数,定义如下函数:
def flog(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
kxy = flog(jfz)
kxy()
# 借助Python的@语法,把decorator置于函数的定义处:
@flog # 调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志
def now(): # 相当于执行了语句:now = flog(now)
print('fuck')
# 由于flog()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,
# 只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在flog()函数中返回的wrapper()函数
# 如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数
# 比如,要自定义flog的文本:
def flog(text):
def decorator(func): # 原来def flog(func)放到了内层,外层传文本text
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
# 这个3层嵌套的decorator用法如下:
@flog('异想家')
def now():
print('fuck')
now() # 显示结果为:异想家 now():\n fuck; now()相当于 now = log('execute')(now)
# 经过decorator装饰之后的函数,它们的__name__已经从原来的'now'变成了'wrapper':
print(now.__name__)
# 需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错
# Python内置的functools.wraps就是干这个事的,一个完整的decorator的写法如下:
import functools
def flog(func):
@functools.wraps(func) # 最后一层函数时用functools.wraps
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
# 针对带参数的decorator:
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
# (jfz)编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志
def belog(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('开始 %s()' % func.__name__)
# f = func(*args, **kw)
# print('结束 %s()' % func.__name__)
# return f
return [func(*args,**kw), print('结束 %s()' % func.__name__)][0] # 网友的巧妙写法
return wrapper
@belog
def now():
print('fuck')
now()
print(now.__name__)
# (jfz)能否写出一个@log的decorator,使它既支持:
# @log
# def f():
# pass
# 又支持:
# @log('execute')
# def f():
# pass
def log(xxx):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
if isinstance(xxx,str):
text = xxx
return decorator
else:
text = '开始'
return decorator(xxx)
@log
def lrz():
print('路然真')
lrz()
print(lrz.__name__)
@log('姐姐')
def lrz():
print('路然真')
lrz()
print(lrz.__name__)
# 偏函数Partial function
print('\n【5、偏函数Partial function】')
# 通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。
print('默认转十进制',int('12'))
print('自定义转八进制',int('12',base=8))
print('自定义转十六进制',int('12',16))
# 要转换大量的二进制字符串,定义一个int2()的函数,默认把base=2传进去:
def int2(x, base=2):
return int(x, base)
# functools.partial就是帮助我们创建一个偏函数, 可以直接使用下面的代码创建一个新的函数int2:
import functools
intp2 = functools.partial(int, base=2)
print('偏函数转二进制',intp2('11111'))
# 【总结】functools.partial的作用就是把一个函数的某些参数给固定住,返回一个新的函数
# 也可以在函数调用时传入其他值:
print('偏函数转八进制',intp2('11', base=8))
# 创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数,当传入:
# int2 = functools.partial(int, base=2)相当于:
# kw = { 'base': 2 }
# int('10010', **kw)
max2 = functools.partial(max, 10) # 把10作为*args的一部分自动加到左边
print('加了10的求最大',max2(5, 6, 7)) # 相当于:args = (10, 5, 6, 7);max(*args)
# 【16】模块Module
print('\n\033[1;31m【16】模块Module\033[0m\n')
# 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,一个.py文件就称之为一个模块Module
# 最大的好处是大大提高了代码的可维护性。
# 其次,编写代码不必从零开始。
# 使用模块还可以避免函数名和变量名冲突。
# Python的所有内置函数:https://docs.python.org/3/library/functions.html
# 例如:一个abc.py的文件就是一个名字叫abc的模块
# 如果不同的人编写的模块名相同怎么办?
# 为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)
# 方法是选择一个顶层包名,比如sandeepin,按照如下目录存放:
# -sandeepin
# - abc.py
# - jfz.py
# 现在,abc.py模块的名字就变成了sandeepin.abc
# 【注意】__init__.py文件必须存在,否则Python就把这个目录当成普通目录,而不是一个包。
# 类似的,可以有多级目录,组成多级层次的包结构。如fuck.bitch.shit
import sandeepin.poi.poilib
sandeepin.poi.poilib.poi()
# [使用模块]模板
# #!/usr/bin/env python3
# # -*- coding: utf-8 -*-
# ' a test module '
# __author__ = 'Sandeepin'
import sys
def test():
# sys模块有一个argv变量,用list存储了命令行的所有参数。
# argv至少有一个元素,因为第一个参数永远是该.py文件的名称
# 运行python3 hello.py jfz获得的sys.argv就是['hello.py', 'jfz']
args = sys.argv
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')
# 当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__
# 如果在其他地方导入该hello模块时,if判断将失败
# 因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码
if __name__=='__main__':
test()
# 启动Python交互环境,再导入hello模块, 没有打印Hello, word!,因为没有执行test()函数。
# [作用域]
# 在一个模块中,有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用
# 在Python中,是通过_前缀来实现,正常的函数和变量名是公开的(public),可以被直接引用
# 类似_xxx和__xxx这样的函数或变量就是非公开的(private),【不应该】被直接引用,比如_abc,__abc等
# private函数和变量不是【不能】被直接引用,是因为Python没有一种方法可以完全限制访问private函数或变量
def _private_1(name):
return 'Hello, %s' % name
def _private_2(name):
return 'Hi, %s' % name
def greeting(name):
if len(name) > 3:
return _private_1(name)
else:
return _private_2(name)
# 我们在模块里公开greeting()函数,而把内部逻辑用private函数隐藏起来
# 【技巧】外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public
print(greeting('jfz'))
print(greeting('Sandeepin'))
print(_private_1('San')) # 并不限制用
print(_private_2('sss'))
# [安装第三方模块]
# 在Python中,安装第三方模块,是通过包管理工具pip完成的
# 比如安装Pillow的命令就是:pip install Pillow
# 图片生成缩略图
from PIL import Image
def JfzBlogImgThumb(ImgName):
im = Image.open(ImgName)
print(im.format, im.size, im.mode)
if max(im.size[0], im.size[1]) > 1000:
if im.size[0] > im.size[1]:
im.thumbnail((1280, 1280))
else:
im.thumbnail((1000, 1000))
im.save('thumb\\'+ImgName, 'JPEG')
return 'OK'
JfzBlogImgThumb('1.jpg')
最后附上廖雪峰的教程地址:https://www.liaoxuefeng.com/wiki/1016959663602400
如果学习的话,更推荐直接阅读他的教程,讲得更详细。
- 上一篇: OpenCV2.4.13+VS2013配置方法
- 下一篇: Qt下Eigen矩阵函数库的添加