函数结构
函数的参数
参数组合
不同类型的参数是有顺序的,依次是必选参数、默认参数、可变参数和关键字参数;
默认参数一定要用不可变对象,用可变对象容易产生逻辑错误;
*args表示的是可变参数,*args接收的是一个元组;
**kw表示的是关键字参数,**kw接收的是一个字典
# 定义一个包含必选参数、默认参数、可变参数和关键字参数的函数plus
def plus(x, y, z=0, *args, **kw):
print('x=',x)
print('y=',y)
print('z=',z)
print('args=',args)
print('kw=',kw)
# 调用函数plus,输入两个参数1,2
plus(1,2)
输出结果:
x= 1
y= 2
z= 0
args= ()
kw= {}
# 定义一个包含必选参数、默认参数、可变参数和关键字参数的函数plus
def plus(x, y, z=0, *args, **kw):
print('x=',x)
print('y=',y)
print('z=',z)
print('args=',args)
print('kw=',kw)
# 调用函数plus,输入参数x=1,y=2,z=3,args=(4,5,6),kw={}
plus(1,2,3,4,5,6)
print('\n')
# 调用函数plus,输入参数x=1,y=2,z=3,args=(4,5,6),kw={'k':7, 'm':8}
plus(1,2,3,4,5,6,k=7,m=8)
输出结果:
x= 1
y= 2
z= 3
args= (4, 5, 6)
kw= {}
x= 1
y= 2
z= 3
args= (4, 5, 6)
kw= {'k': 7, 'm': 8}
函数的返回值ruturn
数值作为返回值
只能有一个ruturn,可以返回多个值
def f():
return 1,'abc','1234'
print(f())
输出结果:
(1, 'abc', '1234')
函数作为返回值
# 定义求和函数,返回的并不是求和结果,而是计算求和的函数
def lazy_plus(*args):
def plus():
s = 0
for n in args:
s = s + n
return s
return plus
f = lazy_plus(1,2,3,4,5)
# 调用lazy_plus()时,返回的并不是求和结果,而是求和函数
print(f)
# 调用函数f时,得到真正求和的结果
print(f())
输出结果:
<function lazy_plus.<locals>.plus at 0x000001DAC97F9950>
15
在函数lazy_plus中又定义了函数plus,而且内部函数plus是可以引用外部函数lazy_plus的参数和局部变量的。当函数lazy_plus返回函数plus时,相关参数和变量也将会保存在返回的函数中,这种方式也称为“闭包”(Closure)
python作用域
- List item
在 Python 中,正常的函数和变量名是公开的(public),是可以被直接引用的。比如abs()、abc、dir()等。
类似__xxx__这种格式的变量是特殊变量,允许被直接引用,但是会被用作特殊用途。比如__author__、__name__就是属于特殊变量。hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己编程定义的变量一般不会用这种变量名。
类似_xxx和__xxx这种格式的函数和变量就是非公开的(private),不应该被直接引用。
补充:_xxx的函数和变量是protected,我们直接从外部访问不会产生异常。__xxx的函数和变量是private,我们直接从外部访问会报异常,我们要注意前缀符号的区别。
循环结构
While 循环与 break 语句
while语句
while 判断条件1:
循环语句
break语句
while 判断条件1:
循环语句
判断条件2:
break
for 循环与 continue 语句
基本形式
iteration_var泛指:不局限于数值型。可以是字符
for iteration_var in sequence:
循环语句
if 判断语句1:
continue
如果判断语句1为真,则执行continue语句,跳出当前循环,直接进入下一次循环。
list = ['python','java','c','c++']
count = 0
for book in list:
count += 1
if count == 3:
continue
print("当前书籍为:",book)
输出结果:
当前书籍为: python
当前书籍为: java
当前书籍为: c++
循环嵌套
for iteration_var in sequence:
for iteration_var in sequence:
循环语句
while 判断条件:
while 判断条件:
循环语句
range 函数
range(start, stop[, step])
start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
>>>range(10) # 从 0 开始到 9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11) # 从 1 开始到 10
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5) # 步长为 5
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3) # 步长为 3
[0, 3, 6, 9]
>>> range(0, -10, -1) # 负数
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]
迭代器
迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源。迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完。迭代器有两个方法:
iter()和next()
迭代对象 python中可迭代的对象有list(列表)、tuple(元组)、dirt(字典)、str(字符串)set等。
1.可迭代对象不一定是迭代器。
2.迭代器一定是可迭代对象。
3.容器类型(list tuple dict str set )是可迭代对象但不是迭代器。
可以被next()函数调用并不断返回下一个值的对象称为迭代
num = next(IteratList)
所有的Iterable(可迭代对象)都可以通过iter()函数转化为Iterator
IteratList = iter(List)
复制迭代器
迭代器当一次迭代完毕后就结束了,在此调用便会引发StopIteration异常。如果想要将迭代器保存起来,可以使用复制的方法:copy.deepcopy():x = copy.deepcopy(y)
,不可使用赋值的方法,这样是不起作用的
创建迭代器
from collections import Iterable
from collections import Iterator
import time
class Classmate(object):
"""定义一个同学类"""
def __init__(self):#初始化
self.name = list()
self.name_num = 0
def add(self,name):#增加成员
self.name.append(name)
def __iter__(self):#必须包含
return self # 返回本身
def __next__(self):#必须包含,调用下一个
if self.name_num < len(self.name):
ret = self.name[self.name_num]
self.name_num += 1
return ret
# 抛出异常,当循环后自动结束
else:
raise StopIteration
class1 = Classmate()
class1.add("张三")
class1.add("李四")
class1.add("王五")
print("判断是否是可迭代的对象:", isinstance(class1,Iterable))
print("判断是否是迭代器:", isinstance(class1,Iterator))
for name in class1:
print(name)
time.sleep(1)
顺序与选择结构
顺序结构
选择结构
if 判断语句1:
step1
else:
step2
if 判断语句1:
step1
elif 判断语句2:
step2
elif 判断语句3:
step3
……
else:
step
三元操作符
result = x if x < y else y
其中,x < y为判断语句。若x < y为真则result = x,否则result = y
内置函数
数学运算
abs():返回数值的绝对值,例如:
>>> abs(-4)
4
divmod():返回两个数值的商和余数,例如:
>>> divmod(7,2)
(3,1)
max():返回元素中的最大值,例如:
>>> max(2,6,1,7)
7
min():返回元素中的最小值,例如:
>>> min(2,6,1,7)
1
sum():返回传入元素之和,例如:
>>> sum((1,2,3,4))
10
>>> sum([1,2,3,4])
10
>>> sum((1,2,3,4),-10)
0
类型转换
bool():根据传入的参数的逻辑值创建一个新的布尔值,例如:
>>> bool()
False
>>> bool(1)
True
>>> bool(0)
False
>>> bool('str')
True
int():根据传入的参数创建一个新的整数,例如:
>>> int('3')
3
>>> int('3.6')
3
float():根据传入的参数创建一个新的浮点数,例如:
>>> float() # 不提供参数的时候,返回0.0
0.0
>>> float(3)
3.0
>>> float('3')
3.0
complex():根据传入的参数创建一个新的复数,例如:
>>> complex() # 当两个参数都不提供时,返回复数0j
0j
>>> complex('2+4j')
(2+4j)
>>> complex(1,2)
(1+2j)
序列操作
all():判断可迭代对象的每个元素是否都为True值,例如:
>>> all([1,2,3]) # 列表中每个元素逻辑值均为True,返回True
True
>>> all([0,1,2]) # 列表中0的逻辑值为False,返回False
False
>>> all(()) # 空元组
True
any():判断可迭代对象的元素是否有为True值的元素,例如:
>>> any([0,1,2]) # 列表元素有一个为True,则返回True
True
>>> any([0,0]) # 列表元素全部为False,则返回False
False
>>> any([]) # 空列表
False
sorted():对可迭代对象进行排序,返回一个新的列表。例如:
>>> a = ['a','b','d','c','B','A']
>>> a
['a', 'b', 'd', 'c', 'B', 'A']
>>> sorted(a) # 默认按字符ascii码排序
['A', 'B', 'a', 'b', 'c', 'd']
对象操作
help():返回对象的帮助信息;
dir():返回对象或者当前作用域内的属性列表。
交互操作
print():向标准输出对象打印输出;
input():读取用户输入值。
文件操作
open():使用指定的模式和编码打开文件,返回文件读写对象。例如:
# t为文本读写,b为二进制读写
>>> a = open('test.txt','rt')
>>> a.read()
some text
>>> a.close()
模块
模块的定义
在 Python 程序的开发过程中,为了代码维护的方便,我们可以把函数进行分组,分别放到不同的.py文件里。这样,每个文件包含的代码就相对较少,这个.py文件就称之为一个模块(Module)。
模块的引入
模块名.函数名
上述方法引入模块的时候,调用函数必须加上模块名
import math
print(math.fabs(-2))
from 模块名 import 函数名1,函数名2....
from math import *
引入模块的所有函数
调用函数时就只能给出函数名,而不能给出模块名。这种导入函数的方式会有一种缺陷,就是当两个模块中含有相同名称函数的时候,后面一次导入的函数会覆盖前一次导入的函数。
内置模块
- os模块:文件和目录,用于提供系统级别的操作;
- sys模块:用于提供对解释器相关的操作;
- json模块:处理JSON字符串;
- logging: 用于便捷记录日志且线程安全的模块;
- time&datetime模块:时间相关的操作,时间有三种表示方式;
- hashlib模块:用于加密相关操作,代替了md5模块,主要是提供SHA1、SHA224、SHA256、SHA384、SHA512和MD5算法;
- random模块:提供随机数
内置模块中的内置函数
dir()函数
dir()函数是一个排好序的字符串列表,其内容是一个模块里定义过的名字,包含在一个模块里定义的所有模块、变量和函数。
globals()和locals()函数
globals()和locals()函数可被用来返回全局和局部命名空间里的名字。如果在函数内部调用的是globals()函数,那么返回的是所有在该函数里能够访问的全局名字。如果在函数内部调用的locals()函数,返回的是能够在该函数里访问的局部命名。globals()函数和locals()函数的返回类型都是字典,所以名字们能用keys()函数摘取。
reload()函数
当一个模块被导入到一个脚本中后,程序只会将模块顶层部分的代码执行一次。因此,如果我们想再次执行模块顶层部分的代码,可以用reload()函数。该函数便会重新将之前导入过的模块导入。
经典函数
递归函数——汉诺塔
汉诺塔问题源于印度一个古老传说。相传大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上并规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。
在编程语言中,如果一种计算过程的其中每一步都会用到前一步或前几步的结果,这个计算过程就可以称为递归的。而用递归计算过程定义的函数,则被称为递归函数。
def move(n, a, b, c):
if(n == 1):
print(a,"->",c)
return
move(n-1, a, c, b)
move(1, a, b, c)
move(n-1, b, a, c)
move(3, "a", "b", "c")
lambda函数
lambda函数又称匿名函数,匿名函数顾名思义就是没有名字的函数。匿名函数不需要return来返回值,lambda函数表达式本身的计算结果就是返回值。
f = lambda x,y:x+y
print(f(1,2))
Map-Reduce - 映射与归约的思想
map()函数
map()函数会根据传入的函数对指定的序列做映射。map()函数接收两个参数,一个是function函数,另一个参数是一个或多个序列
r = map(lambda x: x ** 2, [1, 2, 3, 4,])
print(list(r))
输出结果:
[1, 4, 9, 16]
多参数时
r = map(lambda x, y: x + y, [1, 2, 3, 4, 5], [6, 7, 8, 9, 10])
print(list(r))
输出结果:
[7, 9, 11, 13, 15]
reduce()函数
reduce()函数把传入的函数作用在一个序列[x1, x2, x3, …]上,且这个函数必须要接收两个参数。reduce()函数把第一次计算的结果继续和序列中的下一个元素做累积计算。
from functools import reduce
r = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5],6)
print(r)
输出结果:
21
程序的计算顺序为((((((1+6)+2)+3)+4)+5))