【】

目录

一、函数

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)数列

python函数中传字典 python函数传入字典_python

# 迭代法
>>> 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()