【】
目录
一、函数
1.基础
2.变量作用域
3.迭代器和生成器
4.函数式编程
5.递归(recursion)
二、字典和集合
1.字典的创建和访问
2.字典的内置方法
3.字典遍历技巧
4.集合
一、函数
1.基础
(1)创建和调用:def myfunction(): 下面接代码;调用则直接 myfunction()
(2)参数调用:def myfunction(参数): 下面接带参数的代码;调用则直接myfunction(参数),参数可以为多个
(3)返回值:无需定义返回值类型,无返回值时默认返回None,返回多个值则默认以元组形式打包
(4)形参(parameter)和实参(argument):形参指代一个位置、一个变量名;实参是具体内容
(5)文档创建和调用:
# 创建文档内容
>>> def fileName(dollar):
... """
... 作用:汇率转换,美元 -> 人民币
... 汇率:6.54
... 日期:2222-22-22
... """
... return dollar * 6.54
>>> fileName(10)
65.4
# 查看内容
# 方法一: print()
>>> print(fileName.__doc__)
作用:汇率转换,美元 -> 人民币
汇率:6.54
日期:2222-22-22
# 方法二: help()
>>> help(fileName)
作用:汇率转换,美元 -> 人民币
汇率:6.54
日期:2222-22-22
(6)收集参数:也称可变参数,将标志为收集参数的参数们打包成一个元组,def test(*收集参数名): ;若收集参数后还有其他参数(def test(*收集参数,其他参数): ),则调用函数的时候应采用关键参数进行指定
(7)星号(*):收集参数前面的星号(*)的作用是将多个参数打包成一个元组来进行存储;在形参中作用为“打包”,实参中进行“解包”
(8)print()原型:print(*objects,sep=' ',end='\n',file=sys.stdout,flush=False) ;objects 为收集参数,sep 指定参数之间的分隔符,end 指定结束字符,file 指定输出位置,flush 指定是否强制刷新缓存
2.变量作用域
(1)函数内部修改全局变量:在函数内部试图修改全局变量的值(即建立一个与该全局变量同名的局部变量),全局变量的值不变,但函数内采用两个同名变量中的局部变量的值进行运算
(2)global 关键字:函数内部采用 global + 全局变量 可修改全局变量的值;函数中修改全局变量可能会导致程序可读性变差、出现BUG、代码维护程度成倍提高
>>> count = 5
>>> def myfun():
... global count
... count = 10
... print(count)
>>> myfun()
10
>>> count
10
>>> def myfun1():
... count = 5
... print(count)
>>> myfun1()
5
>>> count
10
(3)嵌套函数:内部函数整个作用域都在外部函数内,在其他地方调用内部函数则会报错
# 内部函数可以引用外部函数的局部变量;
>>> def fun():
... x = 666
... def fun1():
... print(x)
... fun1()
>>> fun()
666
# 函数体要放在被调用的语句之前
>>> def fun2():
... print '123'
>>> def fun2():
... print '456'
>>> fun2()
456
(4)LEGB原则:针对名字相同但作用域不同的变量引用,变量查找顺序为L-E-G-B
L-local:函数内的名字空间
E-Enclosing funtion locals:嵌套函数中外部函数的名字空间
G-Global:函数定义所在模块的名字空间
B-Builtin:Python内置模块的名字空间
(5)闭包(closure):为了尽可能避免使用全局变量,提高代码可重复使用性
# 在一个内部函数里对在外部作用域的变量进行引用,则这个内部函数就是一个闭包
>>> def funX(x):
... def funY(y):
... return x * y
... return funY
>>> temp = funX(5)
>>> temp(8)
40
# 在内部函数中,只能对外部函数进行访问,但不能进行修改
>>> def funX():
... x = 5
... def funY():
... x = x + 1 # err,不可修改
... return x
... return funY
# 可将嵌套函数中的外部变量的值存放在容器中,而容器类型不存放在栈里,所以不会报错
>>> def funX():
... x = [5]
... def funY():
... x[0] = x[0] + 1
... return x[0]
... return funY
>>> temp = funX()
>>> temp()
6
# nonlocal x 可以使嵌套函数中的非全局变量的外部变量变成局部变量
>>> def funX():
... x = 5
... def funY():
... nonlocal x
... x = x + 1
... return x
... return funY
>>> temp = funX()
>>> temp()
6
(6)装饰器(decorator):将被装饰的函数当作参数传递给与装饰器对应(名称相同)的函数,并返回包装后的被装饰的函数
# 装饰器
>>> def log(func):
... def wrapper(): # wrapper() 是 log() 的闭包
... print("开始调用...")
... func()
... print("结束调用...")
... return wrapper
... def eat():
... print("吃吃吃!")
>>> eat = log(eat) # 装饰
>>> eat()
开始调用...
吃吃吃!
结束调用...
# 语法糖
>>> def log(func):
... def wrapper(name):
... print("开始调用...")
... func(name)
... print("结束调用...")
... return wrapper
... @log
... def eat(name):
... print("%s吃吃吃!" % name)
>>> eat("Carl")
开始调用...
Carl吃吃吃!
结束调用...
# 针对被装饰的函数,定义多个参数的时候可采用收集参数 *parameters ,将多个参数打包到一个元组中
# 调用时采用 * 进行解包
3.迭代器和生成器
(1)迭代器:迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。迭代器有两个基本的方法:iter() 和 next()。
>>> import sys # 引入 sys 模块
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> while True:
... try:
... print (next(it)) # 输出迭代器的下一个元素
... except StopIteration: # StopIteration 异常用于标识迭代的完成,防止出现无限循环
... sys.exit()
1
2
3
4
创建迭代器:把一个类作为一个迭代器使用需要在类中实现两个方法__ iter__() 和 __ next__() 。
① __ iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
② __ next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
# 创建一个返回数字的迭代器,初始值为 1,逐步递增 1
>>> class TestNum:
... def __iter__(self):
... self.a = 1
... return self
>>> def __next__(self):
... if self.a <= 5:
... x = self.a
... self.a += 1
... return x
... else:
... raise StopIteration # if 条件不满足时,提示 StopIteration 的错误信息
>>> testcls = TestNum()
>>> testit = iter(testcls)
>>> print(next(testit))
1
>>> for i in testit:
... print(i, end = ' ')
1 2 3 4 5
(2)生成器(generator): 使用了 yield 的函数。生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
# 斐波那契数列
>>> import sys
>>> def fibonacci(n): # 生成器函数
... a, b, counter = 0, 1, 0
... while True:
... if (counter > n):
... return
... yield a
... a, b = b, a + b
... counter += 1
>>> f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
>>> while True:
... try:
... print (next(f), end=" ")
... except StopIteration:
... sys.exit()
0 1 1 2 3 5 8 13 21 34 55
4.函数式编程
(1)lambda 关键字:创建匿名函数来简化函数定义过程;
# 普通函数
>>> def add(x,y):
... return x + y
>>> add(1,2)
3
# 闭包转换为 lambda 表达式
>>> def fun1(x):
... return lambda y : x + y
>>> temp = fun1(1)
>>> temp(2)
3
(2)filter() 函数:过滤器,在海量数据中提取有用信息;
# 第一个参数为 None 时,直接将可迭代对象中表示 True 的值筛选出来
>>> temp = filter(None, [0, 1, False, True])
>>> list(temp)
[1, True]
>>> tuple(temp)
(1, True)
# 第一个参数为函数时,则将可迭代对象里的每个元素作为函数的参数进行计算,返回True的值
>>> def test1(x):
... return x % 2
>>> temp = filter(test1, range(10)) # 返回余数为 True 的 x 的值
>>> list(temp)
[1, 3, 5, 7, 9]
# 可联合 lambda 表达式使用
>>> list(filter(lamda x : x % 2, range(10)))
[1, 3, 5, 7, 9]
(3)map() 函数:映射,该内置函数包含两个参数:一个函数,一个可迭代对象;
# 将可迭代对象的每个元素作为函数参数进行运算
>>> list(map(lambda x : x * 2, range(5)))
[0, 2, 4, 6, 8]
# 从所有可迭代对象中依次提取一个元素组成一个元组,再将元组传递给 func() 函数
# 当可迭代对象长度不一致,则以较短的迭代结束为止
>>> list(map(lambda x, y : x + y, [1, 2, 3], [10, 20, 30, 666]))
[11, 22, 33]
5.递归(recursion)
(1)限制递归深度
>>> import sys
>>> sys.setrecursionlimit(10000) #将递归深度限制到合适层级,这里为10000层,设置层级过大则可以通过 Ctrl+C 强制停止程序
(2)求阶乘函数
#非递归版本
>>> def recursion(n):
... result = n
... for i in range(1,n)
... result *= i
... return result
>>> number = int(input('请输入一个整数:'))
>>> result = recursion(number)
>>> print("%d的阶乘是:%d" % (number, result))
#递归版本
>>> def factorial(n)
... if n == 1:
... return 1
... else:
... return n * factorial(n - 1)
>>> number = int(input('请输入一个整数:'))
>>> result = factorial(number)
>>> print("%d的阶乘是:%d" % (number, result))
(3)斐波那契(Fibonacci)数列
# 迭代法
>>> def fab(n):
... a1 = 1
... a2 = 1
... a3 = 1
... if n < 1:
... print('输入错误!')
... return -1
... while (n-2) > 0:
... a3 = a1 + a2
... a1 = a2
... a2 = a3
... n -= 1
... return a3
... result = fab(20)
... if result != -1:
... print('结果为:%d' % result)
# 递归法
>>> def fab(n):
... if n < 1:
... print('输入错误!')
... return -1
... if n == 1 or n == 2:
... return 1
... else:
... return fab(n-1) + fab(n-2)
... result = fab(20)
... if result != -1:
... print('结果为:%d' % result)
(4)汉诺塔
>>> def hanoi(n, x, y, z):
... if n <= 0:
... print('输入数值不合理!')
... return -1
... if n == 1:
... print(x, '-->', z)
... else:
... hanoi(n-1, x, z, y)
... print(x, '-->', z)
... hanoi(n-1, y, x, z)
... n = int(input('请输入汉诺塔的层数:'))
... hanoi(n, 'X', 'Y', 'Z')
二、字典和集合
1.字典的创建和访问
(1)注意:字典由“键”和“值”组成,每一对键值组合称为“项”,可采用zip方法;字典的“键”必须唯一且不可变,可取数值、字符串或元组;“值”可以取任何数据类型且不可变,如字符串、数或元组;字典不支持拼接和重复操作
(2)字典的创建:用 dict() 内置函数,基础语法为 dict((('key',value),(),...)) 或 dict([('key',value),(),...]) 或 dict(zip(['key',...],[value,...])) 或 dict(key=value,...) 或 {'key':value,...}
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
(3)字典的访问:dict['key']
2.字典的内置方法
(1)fromkeys():创建并返回一个新字典,基础语法为 fromkeys(seq[,value]) ;第一个参数为为key;第二个参数为value,默认为None
(2)keys(),values()和items():分别返回字典中的“键”、“值”和“项”
(3)get():判断查询的key是否在字典中,基础语法为 get(key[,default]),键不存在时,返回 None,若想返回指定的值则设置第二个参数
(4)clear():清空字典,赋值给其他变量名后,源变量初始化,则被赋值的变量也被初始化
#采用字典初始化,即变量名赋值为一个空字典的方法
>>> a = {"a","1","!"}
>>> b = a
>>> b
{"a","1","!"}
>>> a = {}
>>> a
{}
>>> b
{"a","1","!"}
#clear()方法
>>> a = {"a","1","!"}
>>> b = a
>>> b
{"a","1","!"}
>>> a.clear()
>>> a
{}
>>> b
{}
(5)copy():用于拷贝(浅拷贝)整个字典,拷贝后的字典与源字典的id不同
(PS:浅拷贝 和 深拷贝的区别?)
(6)pop() 和 popitem():pop(key[,default]),pop()方法为给定一个key来弹出对应的value;popitem()方法是直接弹出一个项(item),默认为最后一个元素
(7)setdefault():setdefault(key[,default]),类似于 get() 方法,但 setdefault() 方法在字典中找不到相应的key时会进行自动添加
(8)update():update(key="value"),用来更新字典
(9)星号(**):单星号为将收集参数打包为元组,双星号为将收集参数打包为字典,也可用于解包
3.字典遍历技巧
# 同时遍历两个或更多的序列,可以使用 zip() 组合
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(q, a))
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
4.集合
(1)特点:集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。集合会将重复的数据删除。集合是无序的,无法索引。
注:元组不可变,若元组的成员可变类型,则成员可编辑。
>>> a = [1,2,3,4]
>>> b = [5,6,7,8]
>>> c = [9,10,11,12]
>>> t = a,b,c
>>> print(t)
([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12])
>>> del b[1:4]
>>> print(t)
([1, 2, 3, 4], [5], [9, 10, 11, 12])
(2)创建集合:方法一:直接用大括号括起一堆元素;方法二:用 set() 内置函数,可修改列表。
注:如果要创建一个空集合,你必须用 set() 而不是 {} ,后者会创建一个空的字典。
(3)访问集合:迭代方法:for each in set: print(...);判断元素是否在集合中:in 和 not in ;添加元素:add()方法;删除元素:remove()方法
(4)frozenset() 函数:set = frozenset({...}) ,用来 frozen 集合,不能随意增加或删除集合中的元素
(5)集合的推导式:
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}
(6)常用方法:
① 添加元素:
# add() 方法
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.add("Facebook")
>>> print(thisset)
{'Taobao', 'Facebook', 'Google', 'Runoob'}
# update() 方法
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.update({1,3})
>>> print(thisset)
{1, 3, 'Google', 'Taobao', 'Runoob'}
>>> thisset.update([1,4],[5,6])
>>> print(thisset)
{1, 3, 4, 5, 6, 'Google', 'Taobao', 'Runoob'}
② 移除元素:
# remove() 方法
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.remove("Taobao")
>>> print(thisset)
{'Google', 'Runoob'}
# 元素不存在则会发生错误
>>> thisset.remove("Facebook")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Facebook'
# discard() 方法
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.discard("Facebook")
# 元素不存在不会发生错误
>>> print(thisset)
{'Taobao', 'Google', 'Runoob'}
# pop() 方法,随机删除集合中的一个元素
>>> thisset = set(("Google", "Runoob", "Taobao", "Facebook"))
>>> x = thisset.pop()
>>> print(x)
Runoob
③ 计算集合元素个数:
# len() 方法
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> len(thisset)
3
④ 清空集合:
# clear() 方法
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.clear()
>>> print(thisset)
set()