Python基础知识学习-第五天

10-迭代

1 python中那些对象支持for循环(或者说遍历)呢?
答:可迭代的对象,或者说实现了迭代器协议的对象,就支持遍历或循环。(如列表,元组,字典,文件)。特点是内部实现了__next__()方法,能够自动获取下一个元素。实例:

f = open('hello.txt', encoding = 'utf8')
print(f.__next__())
print(f.__next__())
print(f.__next__())
>>>hello, world!

>>>wow!

>>>你好!

若再次调用__next__()方法的话,会抛出StopIteration异常。
也可以调用全局函数next(),如下:

f = open('hello.txt', encoding = 'utf8')
print(next(f))
print(next(f))
print(next(f))
>>>hello, world!

>>>wow!

>>>你好!

同样,此时若再次调用next()函数的话,会抛出StopIteration异常。
注意,列表是常见的可迭代对象,但是却无法调用__next__()方法和next()全局函数:

list1 = [1, 2, 3]
print(list1.__next__())
>>>Traceback (most recent call last):
  File "A:/pycharm/python_workspace/01.05/test01.py", line 2, in <module>
    print(list1.__next__())
AttributeError: 'list' object has no attribute '__next__'
list1 = [1, 2, 3]
print(next(list1))
>>>Traceback (most recent call last):
  File "A:/pycharm/python_workspace/01.05/test01.py", line 2, in <module>
    print(next(list1))
TypeError: 'list' object is not an iterator

但为什么列表可以用for循环遍历呢?因为列表在用for循环遍历时,系统会自动多做一步。可迭代对象可细分为可迭代对象迭代器对象。可迭代对象在遍历时会调用iter()函数生成迭代器,而迭代器对象则已经实现。
测试:文件对象是否已经实现iter()函数?

f = open('hello.txt', encoding = 'utf8')
print(iter(f) is f)
print(f.__next__())
print(next(f))
>>>True
hello, world!

wow!

答案是文件对象已经实现iter()函数。如果是的话,则可以直接使用__next__()方法和next()函数。
测试:列表是否已经实现iter()函数:

list = [1, 2, 3]
print(iter(list) is list)
>>>False

此时也不能调用__next__()方法和next()函数。如果用for循环遍历list的话,会自动实现iter()函数。那可不可以自己实现呢?

list = [1, 2, 3]
i = iter(list)
print(i.__next__())
print(next(i))
>>>1
>>>2

实例,如何手动循环:

list = [1, 2, 3]
res = []
i = iter(list)
while True:
    try:
        res.append(next(i) ** 2)
    except StopIteration:
        break
print(res)
>>>[1, 4, 9]

2 zip()函数
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。
如果需要了解 Pyhton3 的应用,可以参考 Python3 zip()。
zip 语法:
zip([iterable, …])
参数说明:
iterabl – 一个或多个迭代器;
返回值
返回元组列表。
实例:

a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
ziped1 = zip(a, b)
ziped2 = zip(a, c) #元素个数与最短的列表一致
print(list(ziped1))
print(list(ziped2))
>>>[(1, 4), (2, 5), (3, 6)]
>>>[(1, 4), (2, 5), (3, 6)]

11-函数定义与参数

1 Python函数中的变量作用域问题
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

a = 1 #此时a为全局变量
print('outside:', id(a))
def func():
    a = 5 #此时a为局部变量
    print('inside:', id(a))
func()
print(a) #此时a为全局变量
print(id(a))
>>>outside: 8783054934848
>>>inside: 8783054934976
>>>1
>>>8783054934848
a = 1 #此时a为全局变量
print('outside:', id(a))
def func():
    global a #声明a为全局变量
    a = 5 
    print('inside:', id(a))
func()
print(a) #此时a为全局变量
print(id(a))
>>>outside: 8783054934848
>>>inside: 8783054934976
>>>5
>>>8783054934976

2 函数传值的相关问题
不可变类型,传递副本给函数,函数内操作不影响原始值。

def change_num(x):
    x += 10
x = 5
print('x = {}'.format(x))
change_num(x)
print('x = {}'.format(x))
>>>x = 5
>>>x = 5

可通过以下方式输出函数内部改变了的函数值:

def change_num(x):
    x += 10
    return x
x = 5
print('x = {}'.format(x))
x = change_num(x)
print('x = {}'.format(x))
>>>x = 5
>>>x = 15

可变类型,传递地址引用,函数内操作影响原始值。

def change_list(l):
    l[0] = 99
l = [1, 2, 3, 4]
print('原始列表:', l)
change_list(l)
print('操作后列表:',l)
>>>原始列表: [1, 2, 3, 4]
>>>操作后列表: [99, 2, 3, 4]
发布了7 篇原创文章 · 获赞 0 · 访问量 93

猜你喜欢

转载自blog.csdn.net/Mr_Wang0120/article/details/104008858