函数名的使用,迭代器

函数名的使用

函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量

1.函数名的内存地址
def func():
    print("hehe")
print(func)
结果:<function func at 0x1101e4ea0>
2.函数名可以赋值给其他变量
def func():   
    print("呵呵")
    print(func)
a = func    # 把函数当成一个值赋值给另一个变量
a()     # 函数调用 func()
3.函数名可以当做容器类的元素
def func1():   
    print("呵呵")
def func2():   
    print("呵呵")
def func3():   
    print("呵呵")
def func4():  
     print("呵呵")
lst = [func1, func2, func3]
for i in lst:  
     i()
4.函数名可以作为函数返回值
def func_1():   
    print("这里是函数1")   
    def func_2():       
        print("这里是函数2")   
    print("这里是函数1")   
    return func_2
fn = func_1()  
# 执行函数1.  函数1返回的是函数2, 这时fn指向的就是上面函数2
fn()    # 执行func_2函数


f-string字符串格式化

f-strings 是python3.6开始加入标准库的格式化输出新的写法,这个格式化输出比之前的%s 或者 format 效率高并且更加简化

结构就是F(f)+ str的形式,在字符串中想替换的位置用{}展位,与format类似,但是用在字符串后面写入替换的内容,而他可以直接识别。

name = "小白"
age = 18
sex = "男"
msg = F'姓名:{name},性别:{age},年龄:{sex}'  # 大写字母也可以
msg = f'姓名:{name},性别:{age},年龄:{sex}'  
print(msg)
'''
输出结果:
姓名:小白,性别:18,年龄:男

任意表达式:
print(f'{3*21}') #63
name = 'barry'
print(f"全部大写:{name.upper()}")  #全部大写BARRY

# 字典也可以
teacher = {'name': '', 'age': 18}
msg = f"The teacher is {teacher['name']}, aged {teacher['age']}"
print(msg)  # The comedian is   , aged 18

# 列表也行
l1 = ['', 18]
msg = f'姓名:{l1[0]},年龄:{l1[1]}.'
print(msg)  # 姓名:,年龄:18.

# 插入表达式
def sum_a_b(a,b):
    return a + b
a = 1
b = 2
print('求和的结果为' + f'{sum_a_b(a,b)}')
#多行f
xname = 'barry'
age = 18
ajd = 'handsome'

# speaker = f'''Hi {name}.
# You are {age} years old.
# You are a {ajd} guy!'''

speaker = f'Hi {name}.'\
          f'You are {age} years old.'\
          f'You are a {ajd} guy!'
print(speaker)
#其他
print(f"{{73}}")  # {73}
print(f"{{{73}}}")  # {73}
print(f"{{{{73}}}}")  # {{73}}
m = 21
# ! , : { } ;这些标点不能出现在{} 这里面。
# print(f'{;12}')  # 报错
# 所以使用lambda 表达式会出现一些问题。
# 解决方式:可将lambda嵌套在圆括号里面解决此问题。
x = 5
print(f'{(lambda x: x*2) (x)}')  # 10

迭代器

在python中,但凡内部含有iter方法的对象,都是可迭代对象

通过dir() 去判断一个对象具有什么方法

dir()会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名。
s1 = 'alex'
print(dir(s1))

s1 = 'alex'
i = 100
print('__iter__' in dir(i))  # False
print('__iter__' in dir(s1))  # True

从字面意思来说:可迭代对象就是一个可以重复取值的实实在在的东西。

​ 从专业角度来说:但凡内部含有__iter__方法的对象,都是可迭代对象。

​ 可迭代对象可以通过判断该对象是否有__iter__方法来判断。

​ 可迭代对象的优点:

​ 可以直观的查看里面的数据。

​ 可迭代对象的缺点:

​ 1.占用内存。

​ 2.可迭代对象不能迭代取值(除去索引,key以外)。

在python中,内部含有__Iter__方法并且含有__next__方法的对象就是迭代器。

o1 = 'alex'
o2 = [1, 2, 3]
o3 = (1, 2, 3)
o4 = {'name': '太白','age': 18}
o5 = {1, 2, 3}
f = open('file',encoding='utf-8', mode='w')
print('__iter__' in dir(o1))  # True
print('__iter__' in dir(o2))  # True
print('__iter__' in dir(o3))  # True
print('__iter__' in dir(o4))  # True
print('__iter__' in dir(o5))  # True
print('__iter__' in dir(f))  # True

print('__next__' in dir(o1))  # False
print('__next__' in dir(o2))  # False
print('__next__' in dir(o3))  # False
print('__next__' in dir(o4))  # False
print('__next__' in dir(o5))  # False
print('__next__' in dir(f))  # True
f.close()
只有文件句柄是迭代器,剩下的那些数据类型都是可迭代对象。

可迭代对象如何转化成迭代器:

l1 = [1, 2, 3, 4, 5, 6]
obj = l1.__iter__()
# <list_iterator object at 0x000002057FE1A3C8>
# 或
obj = iter(l1)
print(obj)
# <list_iterator object at 0x102cc67f0

迭代器取值:

​ 可迭代对象是不可以一直迭代取值的(除去用索引,切片以及Key),但是转化成迭代器就可以了,迭代器是利用__next__()进行取值:

l1 = [1, 2, 3,]
obj = l1.__iter__()  # 或者 iter(l1)
# print(obj)  # <list_iterator object at 0x000002057FE1A3C8>
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()  # StopIteration
print(ret)
# 迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,
# 那么就报StopIteration的错误。

​ 从字面意思来说:迭代器就是可以迭代取值的工具。

​ 从专业角度来说:在python中,内部含有__Iter__方法并且含有__next__方法的对象就是迭代器。

迭代器的优点: 节省内存。迭代器在内存中相当于只占一个数据的空间:因为每次取值都上一条数据会在内存释放,加载当前的此条数据。

惰性机制。next一次,取一个值,绝不过多取值。

有一个迭代器模式可以很好的解释上面这两条:迭代是数据处理的基石。扫描内存中放不下的数据集时,要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式。

迭代器的缺点: 不能直观的查看里面的数据。

​ 取值时不走回头路,只能一直向下取值。

l1 = [1, 2, 3, 4, 5, 6]
obj = iter(l1)

for i in range(2):
    print(next(obj))

for i in range(2):
    print(next(obj))

可迭代对象:

​ 是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。

应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。

迭代器:

​ 是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。

应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择

猜你喜欢

转载自www.cnblogs.com/sundawei7/p/11209786.html