1.无global 关键字:当函数中无关键字 global 时,当局部变量与全局变量命名相同,优先读取函数中的变量,函数中无法对全局变量进行修改,但当全局变量的类型为列表时,可对内部的元素进行操作(例:test.append)。
li = ["1",2,3,4,5] def test(): li.append("hello") # 对原有的列表进行操作 # print(li) test() print(li) # 输出 ['1', 2, 3, 4, 5, 'hello']
2.有global关键字
name = "aaaa" def test(): global name name = "bbbb" test() print(name) # 输出 bbbb
# 注:
# 下方的程序会产生报错,在一个函数中既有局部变量,有引用了全局变量(在函数中声明引用全局变量,应将global放于最上方) name = "aaaa" def test(): name = "cccc" global name name = "bbbb" test() print(name) # 报错 File "F:/Python_Project/Test/Test.py", line 242 global name ^ SyntaxError: name 'name' is assigned to before global declaration
## 书写规格 ##
######### 全局变量变量名大写
######### 局部变量变量名小写
# 当一个函数中返回另一个函数的函数名,其实际返回的是该函数的地址,可以直接使用该地址调用该函数 def test1(): print("this is test1()") def test2(): print("this is test2()") return test1 # 返回函数test1()的地址 res = test2() print(res) res() # 当执行函数test2()时,返回了函数test1()的地址,所以res()代指为函数test1() # 执行的结果 this is test2() <function test1 at 0x00000197E46BC378> this is test1()
def one(): print("this is one") def two(): print("this is two") def three(): print("this is three") return three return two test_two = one() # 执行函数one() 返回函数two()的地址 test_three = test_two() # 执行函数two() 返回函数three的地址 test_three() # 执行函数three)
# 注:上面的三步相当于 one()()() # 输出结果 this is one this is two this is three
# nonlocal 指定上一级变量(name 为函数test1()中的name) name = "hello" def test1(): name = "world" def test2(): nonlocal name print(name)
编程语言中的定义:函数直接或间接的调用函数本身,则该函数称为递归函数
再数学中的定义:对于某一函数F(x),其定义域是集合A,那么若对于A集合中的某一个值X0,其函数值F(x0)由F(F(x0))决定,那么就称F(x)为递归函数
## 以下为一个递归,该递归为一个死循环
def clac(n): print(n) clac(n): clac(10)
# 递归所具有的特性
1.函数的递归必须有一个明确的结束条件
2.每次进入更深的一层递归时,问题的规模应当比上次递归有所减少
def test(n): print(n) if int(n/2) == 0: return n return test(int(n/2)) test(10) # 输出 10 5 2 1
# 匿名函数 lambda x:x+1 # x:函数的形参 x+1:为函数的返回值 # 上方匿名函数对应的普通函数 def calc(x): return x+1 func = lambda x:x+1 print(func(10)) # 相当于执行匿名函数 lambda x,y,z:(x+1,y+1,z+1) # 在lambda中返回多个值 得加上括号
1.面向过程:
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向过程其实是最为实际的一种思考方式,就算是面向对象的方法也是含有面向过程的思想。可以说面向过程是一种基础的方法。它考虑的是实际地实现。一般的面向过程是从上往下步步求精,所以面向过程最重要的是模块化的思想方法。对比面向过程,面向对象的方法主要是把事物给对象化,对象包括属性与行为。当程序规模不是很大时,面向过程的方法还会体现出一种优势。因为程序的流程很清楚,按着模块与函数的方法可以很好的组织。比如拿学生早上起来这件事说明面向过程,粗略的可以将过程拟为:(1)起床(2)穿衣(3)洗脸刷牙(4)去学校而这4步就是一步一步地完成,它的顺序很重要,你只需要一个一个地实现就行了。而如果是用面向对象的方法的话,可能就只抽象出一个学生的类,它包括这四个方法,但是具体的顺序就不一定按照原来的顺序。https://baike.baidu.com/item/%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B/9957246?fr=aladdin
2.面向对象:
向对象是一种对现实世界理解和抽象的方法...待补充
3.函数式编程:
待补充
### map()函数
## 第一种例子 num_l = [1,2,3,4,5] def add_one(x): x = x + 1 return x def map_test(func,array): ret = [] for i in array: res = func(i) # 调用函数add_one() 后返回计算后的值 ret.append(res) # 将得到的值追加到列表ret中 return ret print(map_test(add_one,num_l)) # 传入执行自加一的函数 传入源列表 # 结果 [2, 3, 4, 5, 6] ## 第二种写法 利用抽象函数 num_l = [1,2,3,4,5] def map_test(func,array): ret = [] for i in array: res = func(i) # 利用抽象函数进行计算 ret.append(res) # 将得到的值追加到列表ret中 return ret print(map_test(lambda x:x+1,num_l)) # 利用抽象函数 传入源列表 print(map_test(lambda x:x-1,num_l)) # 结果 [2, 3, 4, 5, 6] [0, 1, 2, 3, 4] ## 第三种写法 利用map函数 num_l = [1,2,3,4,5] res = map(lambda x:x+1,num_l) print(list(res)) ### 在python3.5中此时得到的是一个可迭代对象 <map object at 0x000001EA24F68240> ### 在python2.7中直接得到的是一个列表[2, 3, 4, 5, 6, 7, 8]
# 将一个字符串转成大写形式,列表 msg = "helloworld" print(list(map(lambda x:x.upper(),msg))) # 输出['H', 'E', 'L', 'L', 'O', 'W', 'O', 'R', 'L', 'D']
### filter()函数
## 过滤掉末尾以 sb 结尾的字符串 ### 第一种写法 name = ['aaaa_sb','bbbb_sb','cccc_sb','dddd'] def end_filter(n): return n.endswith("sb") def filter_test(func,array): res = [] for p in array: if not func(p): res.append(p) return res print(filter_test(end_filter,name)) # 输出['bbbb'] ### 第二种写法 name = ['aaaa_sb','bbbb_sb','cccc_sb','dddd'] def filter_test(func,array): res = [] for p in array: if not func(p): res.append(p) return res print(filter_test(lambda x:x.endswith("sb"),name)) # 输出['bbbb'] ### 第三种写法 利用filter函数 name = ['aaaa_sb','bbbb_sb','cccc_sb','dddd'] print(list(filter(lambda x:not x.endswith('sb'),name))) # 输出['bbbb']
### reduce
# 在Python2种可以直接使用该函数
# 咋Python3种得导入该模块
from functools import reduce(重模块functools种导入函数reduce )
### 第一种写法 from functools import reduce num_list = [1,2,3,4,5] def reduce_test(func,array): res = array.pop(0) for num in array: res = func(res,num) return res print(reduce_test(lambda x,y:x+y,num_list)) print(reduce_test(lambda x,y:x*y,num_list)) ### 第二种写法 利用reduce函数 print(reduce(lambda x,y:x+y,num_list)) print(reduce(lambda x,y:x*y,num_list))
总结:
map:对原有的数据进行加工,处理列表中的每个元素,得到的结果是一个“列表”(迭代器的形式),该列表的个数及位置与原来一样
filter:对数据进行过滤(遍历序列中的每个元素,判断每个元素得到布尔值,如果为True则留下来)
reduce:对原有的数据进行压缩(相加 相乘)
其它内置函数:
abs() # 取绝对值 all() # 对序列中的元素进行布尔运算(0,None,空字符串为假),序列中的元素一个为假 则为假 any() # 序列中的元素有一个为真 则为真 bool() # 判断布尔值(0,None,空字符串 为False)其余的为True hex() # 十进制转十六进制 oct() # 十进制转八进制 bin() # 将十进制转为二进制 bytes() # 将一个字符串转成字节的形式 name = "你好中国" ret = bytes(name,encoding="utf-8") print(bytes(ret) # 得指定编码方式 # 输出的结果为 'xe4xbdxa0xe5xa5xbdxe4xb8xadxe5x9bxbd' print(ret.decode("UTF-8")) # 进行解码(注何种编码格式编码,就用各种编码格式解码) # 输出的结果为 你好中国 chr() # 按照ASCII码变进行对应的转换 ord(97) # 显示在ASCII码中对应的字符 dir() # 打印某个对象中所有的方法 例如dir(all) divmod() # divmod(10,3) 输出的结果为(3,1),输出商和余数 eval() # 功能一 # 将字符串中的数据结构提取出来 dic = {"name": "henry"} # 定义一个字典 dic_str = str(dic) # 将其转换成字符串的形式 print(dic_str) d = eval(dic_str) # 将字符串中的字典提取出来 print(d["name"]) # 功能二:将字符串中的表达式进行算术运算 num_list = "1+2+3-4*5/6" print(eval(num_list)) hash() # 可hash的数据类型为不可变数据类型,不可hash的数据即可变的数据类型 # 不管所给的字符串有多长,相同数据得到的哈希数相同(注意每次运行都会得到一个新的值) # 不能根据得到的哈希值进行反推得到原来的字符串 # hash可以用来判断文件或数据有没有被修改过 name = "你好中国" print(hash(name)) # 7099912592138176852 help() # 用于打印一个方法的具体使用方法help(all) print(isinstance(1, int)) # 判断1是否是int型,返回布尔值 print(isinstance('abc', str)) # 判断abc是否是str型 print(isinstance([], list)) # 判断是否为列表类型 print(isinstance({}, dict)) # 判断是否为字典类型 globals() # 打印全局的所有变量 locals() # 打印局部变量 num_list = [1, 2, 3, 4] min(num_list) # 取列表最大值 max(num_list) # 取列表最小值(传入的数据类型是一个可迭代类型) # 1.max函数处理的是可迭代的对象,相当于一个for循环取出每个元素进行比较。注意:不同类型元素之间不能进行比较 # 2.每个元素间进行比较,是从每个元素的第一个位置一次比较,如果这个位置分出大小后,后面的则不需要进行比肩 dic = {"name": "hh", "age", 18} max(dic) # 比较的是key max(dic.values()) # 比较的是value 无法得到与Key相对应 # zip(a序列,b序列) a序列与b序列为一一对应的关系 # 序列包括 列表 元组 字符串 # 元组 print(list(zip(("a", "b", "c"), (1, 2, 3)))) # 输出的为 [("a",1),("b",2),("c",3)] print(list(zip(("a", "b", "c"), (1, 2, 3, 4)))) # 输出也为[("a",1),("b",2),("c",3)] print(list(zip(("a", "b", "c", "d"), (1, 2, 3)))) # 输出也为[("a",1),("b",2),("c",3)] # 字符串 print(zip("hello", "12345")) # [('h', '1'), ('e', '2'), ('l', '3'), ('l', '4'), ('o', '5')] print(zip(["h", "e", "l", "l", "o"], ["1", "2", "3", "4", "5"])) # [('h', '1'), ('e', '3'), ('l', '2'), ('o', '5')] p = {"name": "henry", "age": 18} print(list(zip(p.keys(), p.values()))) # [("name","henry"),("age",18)] # zip和max配合使用_初级玩法 # 取出一个字典中最大的年纪 >> > age_dic = {'a_age': 18, 'b_age': 30, 'c_age': 10} >> > print(max(zip(age_dic.values(), age_dic.keys()))) # 先用zip将其转为元组模式 在进行比较 (30, 'b_age') >> > num_list = ["a1", "a2", "a3", 100] print(max(num_list)) # 会报错 不同的数据类型间不能比较 # zip和max配合使_终极玩法 people = [ {"name": "aaa", "age": 19} {"name": "bbb", "age": 13} {"name": "ccc", "age": 12} {"name": "ddd", "age": 11} ] max(people) # 直接报错(字典本身无序,多个字典间不能进行比较) print(max(people, value=lambda dic: dic['age'])) pow(2, 2) # 相当于求2**2 pow(3, 2, 2) # 相当于32次方,对2取余 3**2%2 recursed() # 将一个序列反转(对源序列无影响) round(2.4) # 四舍五入 set() # 将其转为集合形式 print(set("hello")) set(['h', 'e', 'l', 'o']) num_list = "hello" s = slice(3, 5) # 切片 s1 = slice(3, 5,2) # 定义切片步长 a = [3, 4, 5, 3, 3, 2, 6] print(sorted(a)) # 对序列进行排序,实质就是进行比较大小,不同类型的数据元素之间不能进行排序 people = [ {"name": "aaa", "age": 19}, {"name": "bbb", "age": 13}, {"name": "ccc", "age": 12}, {"name": "ddd", "age": 11} ] print(sorted(people, key=lambda dic: dic['age'])) # 对字典的集合进行排序 # [{'name': 'ddd', 'age': 11}, {'name': 'ccc', 'age': 12}, {'name': 'bbb', 'age': 13}, {'name': 'aaa', 'age': 19}] name_dic = { "python": 1, "java": 2, "C": 3 } print(sorted(name_dic, key=lambda key: name_dic[key])) # ['python', 'java', 'C'] a = [1, 2, 3, 5] sum(a) # 求和 type(a) # 查看数据类型 # 根据type判断数据类型 根据不同的数据类型执行不同的逻辑 vars() # 当vars没有参数时,与locas() 的用法相同,打印局部变量 vars(int) # 当有参数时,查看某个对象中的所有方法,以字典的形式显示