记录下python中函数名的应用、格式化输出的其他写法、可迭代对象和迭代器的内容。
在Python中,函数名有以下的用途:
(1)函数名指向内存地址。
def func(): print('我是函数') print(func,type(func)) # <function func at 0x106ecb268> <class 'function'>
(2)函数名是变量,可以赋值。
def func(): print('我是函数') # 函数名是变量 f1=func f2=f1 f3=f2 # f3是可以执行的 f3() # 我是函数
(3)函数名可以作为容器型数据类型的元素,如列表、元祖、集合和字典就是容器型数据类型。
def func1(): print('I am func1') def func2(): print('I am func2') def func3(): print('I am func3') li=[func1,func2,func3] print(li) # [<function func1 at 0x106f89378>, <function func2 at 0x106f892f0>, <function func3 at 0x106f891e0>]
(4)函数名可以作为函数的参数。
def func(fn): fn() def print_circle(): print('你特别喜欢画饼,可惜我吃不下') func(print_circle) # 你特别喜欢画饼,可惜我吃不下
(5)函数名可以作为函数的返回值。
def func1(): print('这是func1') def func2(): print('这是func2') print('这是func1') return func2 fn=func1() fn() 这是func1 这是func1 这是func2
前面学过,可使用%s占位符替换字符串、%d占位符替换数字、format进行格式化输出。
favor=input('你的爱好是:') age=input('你的年龄是:') print('我的爱好是%s,今年我%s'%(favor,age)) print('我的爱好是{},今年我{}'.format(favor,age))
在python3.6之后,可以使用如下方式进行格式化输出,但! , : 等符号不能出现在大括号{}中,以后可结合lamda表达式使用。
favor=input('你的爱好是:') age=input('你的年龄是:') print(f'我的爱好是{favor},今年我{age}') 你的爱好是:football 你的年龄是:18 我的爱好是football,今年我18
{}里可以加表达式、函数。
# 1 可以加表达式 dic={'favor':'football','age':18} print(f'我的爱好是{dic["favor"]},今年我{dic["age"]}') # 我的爱好是football,今年我18 li=['football',18] print(f'我的爱好是{li[0]},今年我{li[1]}') # 我的爱好是football,今年我18 print(f'我的爱好是{favor.upper()},今年我{age}') # 我的爱好是FOOTBALL,今年我18 # 2 可以结合函数来写 def my_sum(a,b): return a+b print(f'和为:{my_sum(200,100)}') # 和为:300
这种写法结构简单,一目了然,执行效率也更高。
包含基本概念说明、for循环机制、可迭代对象和迭代器优缺点总结。
可迭代对象遵循可迭代协议,如str、list、tuple、dict、set都遵循均为可迭代对象,先看下面例子,str执行for循环没有报错,但是int类型的提示“TypeError: 'int' object is not iterable”,表明int不遵循可迭代协议。
# 可迭代协议 s='abc' for c in s: print(c) s=123 for i in s: print(i) 执行结果如下: Traceback (most recent call last): File "/Users/yangchaolin/pythonCode/day11/05 迭代器01.py", line 30, in <module> for i in s: TypeError: 'int' object is not iterable a b c
内部含有'iter'方法的对象,就是可迭代对象,可以通过dir函数来查看,从下面代码可以看出str类型的对象含有此方法。
# 查看一个对象的所有方法 s1='messi' print(s1.__dir__()) # 判断是否存在这个方法 print('__iter__' in s1.__dir__()) print('__iter__' in dir(s1)) 执行结果: ['__repr__', '__hash__', '__str__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__mod__', '__rmod__', '__len__', '__getitem__', '__add__', '__mul__', '__rmul__', '__contains__', '__new__', 'encode', 'replace', 'split', 'rsplit', 'join', 'capitalize', 'casefold', 'title', 'center', 'count', 'expandtabs', 'find', 'partition', 'index', 'ljust', 'lower', 'lstrip', 'rfind', 'rindex', 'rjust', 'rstrip', 'rpartition', 'splitlines', 'strip', 'swapcase', 'translate', 'upper', 'startswith', 'endswith', 'isascii', 'islower', 'isupper', 'istitle', 'isspace', 'isdecimal', 'isdigit', 'isnumeric', 'isalpha', 'isalnum', 'isidentifier', 'isprintable', 'zfill', 'format', 'format_map', '__format__', 'maketrans', '__sizeof__', '__getnewargs__', '__doc__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__dir__', '__class__'] True True
此外,还可以通过isinstance()函数查看对象是什么类型,可以看出str是可迭代对象,但是不是迭代器。
# 查看对象类型,python3.8之前可以这么导入 from collections import Iterable from collections import Iterator s='messi' print(isinstance(s,Iterable)) print(isinstance(s,Iterator)) 执行结果: True False
什么是迭代器呢,将可迭代对象通过iter()函数进行转换,内部除了含有'iter'方法,还含有'next'方法,就是迭代器,也可以通过以上两种方式判断是否是迭代器。
# 可迭代对象转换为迭代器,并判断类型 s='messi' # 以下两种写法都可以 s_iter=s.__iter__() # s_iter=iter(s) print('__iter__' in s_iter.__dir__()) # True print('__next__' in s_iter.__dir__()) # True
通过'next'方法,可以获取到迭代器中的元素。
# 列表转换为迭代器,然后对迭代器循环打印 li=['messi','ronald','herry'] it=iter(li) # 循环控制次数 for index in range(len(li)): print(next(it)) 执行结果: messi ronald herry
可迭代对象是不能直接取值的,但列表通过for循环可以获取到值,这其实是内部进行了转换,将列表转化成了一个迭代器。
li=[1,2,3,4] print('__iter__' in li.__dir__()) # True,说明列表就是可迭代对象 print('__next__' in dir(li)) # False,说明不是迭代器 for num in li: print(num)
可以使用while循环+迭代器来模拟for循环。
li=[1,2,3,4] li_iter=iter(li) while True: try: i=li_iter.__next__() print(i) except StopIteration: break
迭代器的next函数执行是不走回头路的,执行一次,就走到下一个元素。next一次只取一个元素,这就是迭代器的惰性机制。从下面的例子可以看出,迭代器it执行7次next取值后,后面再执行3次,发现不从开头取值,而是接着从下个元素开始取值。
# 不走回头路 li=[0,1,2,3,4,5,6,77,88,99] it=iter(li) for i in range(7): print(it.__next__()) print('----分割线----') for i in range(3): print(next(it)) 执行结果: 0 1 2 3 4 5 6 ----分割线---- 77 88 99
然而,可迭代对象是可以走回头路的。
count=0 for item in li: if count==7: break else: print(item) count+=1 print('----分割线----') count=0 for item in li: if count==3: break else: print(item) count+=1 执行结果: 0 1 2 3 4 5 6 ----分割线---- 0 1 2
(1)看代码写结果,主要理解函数名的使用。
def func1(): print('I am func1') def func2(x): print('I am func2') return x def func3(y): print('I am func3') return y ret=func2(func1) ret() ret2=func3(func2) ret3=ret2(func1) ret3() 执行结果: I am func2 I am func1 I am func3 I am func2 I am func1
(2)看代码写结果,理解列表为全局命名空间的,方法操作的都是这个li。
li=[] def func(args): li.append(args) return li print(func(1)) print(func(2)) print(func(3)) 执行结果: [1] [1, 2] [1, 2, 3]
(3)看代码写结果,这里主要理解方法的默认参数,l1和l3,其实指向的都是默认参数里的列表,而l2指向的是一个新的列表,所以最后结果会是l1和l3一样。
def magic_list(s,li=[]): li.append(s) return li l1=magic_list(100,) l2=magic_list('messi',[]) l3=magic_list('ronald',) print(f'l1的结果是{l1}') print(f'l2的结果是{l2}') print(f'l3的结果是{l3}') 执行结果: l1的结果是[100, 'ronald'] l2的结果是['messi'] l3的结果是[100, 'ronald']
(4)写一个函数,返回除大小王之外的52张扑克牌,每一项是一个字典[{'红心':2},{'黑桃':1},…],这个主要是体会迭代器的使用。
shape=['红心','黑桃','梅花','方块'] number=[1,2,3,4,5,6,7,8,9,10,'j','Q','K'] shape_it=iter(shape) li=[] for i in range(len(shape)): s=shape_it.__next__() # 下面for循环完后,不能回头,因此需要临时再新建对象 number_it = iter(number) for j in range(len(number)): dic={} dic[s]=next(number_it) li.append(dic) print(li) 执行结果: [{'红心': 1}, {'红心': 2}, {'红心': 3}, {'红心': 4}, {'红心': 5}, {'红心': 6}, {'红心': 7}, {'红心': 8}, {'红心': 9}, {'红心': 10}, {'红心': 'j'}, {'红心': 'Q'}, {'红心': 'K'}, {'黑桃': 1}, {'黑桃': 2}, {'黑桃': 3}, {'黑桃': 4}, {'黑桃': 5}, {'黑桃': 6}, {'黑桃': 7}, {'黑桃': 8}, {'黑桃': 9}, {'黑桃': 10}, {'黑桃': 'j'}, {'黑桃': 'Q'}, {'黑桃': 'K'}, {'梅花': 1}, {'梅花': 2}, {'梅花': 3}, {'梅花': 4}, {'梅花': 5}, {'梅花': 6}, {'梅花': 7}, {'梅花': 8}, {'梅花': 9}, {'梅花': 10}, {'梅花': 'j'}, {'梅花': 'Q'}, {'梅花': 'K'}, {'方块': 1}, {'方块': 2}, {'方块': 3}, {'方块': 4}, {'方块': 5}, {'方块': 6}, {'方块': 7}, {'方块': 8}, {'方块': 9}, {'方块': 10}, {'方块': 'j'}, {'方块': 'Q'}, {'方块': 'K'}]
(5)python版本的九九乘法表。
for i in range(1,10,1): s='' for j in range(1,i+1,1): if j!=i: # 不到最后,需要用分隔符隔开 s+=str(i)+'*'+str(j)+'='+str(i*j)+'\t' else: # 到了最后,不需要用分隔符隔开 s+=str(i)+'*'+str(j)+'='+str(i*j) # 打印 print(s) 执行结果: 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
PS:以上,理解不一定正确,学习就是一个不断认识和纠错的过程,如果有误还请批评指正。
参考博文:
(1)https://www.cnblogs.com/pingwen/p/12634614.html 容器型数据类型
(2)https://www.cnblogs.com/youngchaolin/p/12323797.html#_label2_10 format格式化
(3)https://www.cnblogs.com/youngchaolin/p/10963219.html#_label1 %s %d