Python基础(Day5)(迭代 函数)

知识点总结:

迭代器(Iterator),可迭代对象(Iterable)

  • Iterable: 具有方法__iter__()的对象。该方法返回一个Iterator
  • Iterator: 具有方法__next__()的对象__next__()可以被直接调用,迭代到超过末尾会抛出异常。同时具有__iter__()返回自身即可。

所以迭代器一定是可迭代对象!!!

通过for迭代Iterable

# 通过for迭代tuple
for i in (1, 2, 3):
    print(i)

# 通过for迭代dict
for k, v in {'k1': 'key', 'k2': 'value2'}.items():
    print(k, v)

# 通过for迭代一个file,按行迭代
# 实际open()返回的是一个stream, Iterator类型
f = open('data.txt', 'r', encoding='utf8')
for line in f:
	print(line)
  • 注意: list/dict/tuple等为可迭代对象。实际for的底层会调用其__iter__()得到Iterator进而调用__next__(), 下面介绍
  • print(isinstance(i, Iterable)) 判断是否为Iterable
  • print(isinstance(i, Iterator)) 判断是否为Iterator
from collections import Iterable, Iterator
>>> i = []
>>> isinstance(i, Iterable)
True
>>> isinstance(i, Iterator)
False
# i 具有__iter__()方法,其为Iterable可迭代对象
>>> i.__iter__()
<list_iterator object at 0x00000280FD9490B8>
iter() 说明
'''
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator

Get an iterator from an object.  In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
'''
  • 可用iter()封装list,将list(可迭代对象)转为Iterator迭代器
  • 调用iter()获得迭代器的两种方式
l = [1, 2, 3]

# 1. 之际调用Iterable的__iter__()方法
l.__iter__()

# 2. 通过函数iter()获取迭代器
iter(l)

# 得到Iterator后可进而调用next()获得值
print(l.__iter__().__next__())
  • 调用next()迭代方法的两种方式
# 1. 直接调用对象__next__()方法
print(f.__next__())

# 2. 通过函数next()调用
print(next(f))
urls = ['www.baidu.com', 'mp.csdn.net']
i = iter(urls)
  • 多种方式实现迭代list
l = [1,2,3]
res = []

# 用for实现
for x in l:
    res.append(x**2)

# 用iter()实现相同功能
i = iter(l)
while True:
    try:
        res.append(next(i)**2)
    except StopIteration:
        break
res = [x**2 for x in l]
print(res)

# 用推导实现相同功能
l = [1, 2, 3, 4]
res = [x for x in l if x % 2 == 0]
print(res)

生成内置可迭代对象的函数介绍(Iterable 具有__iter__())

# 1. range()
r = range(0, 5)
for i in r:
    print(i)

# 输出
0
1
2
3
4


# 2. zip() 合并集合
result = zip(['x', 'y', 'z'], [1, 2, 3])
for i in result:
    print(i)

# 输出
('x', 1)
('y', 2)
('z', 3)


# 3. map()
def times_two(x):
    x *= 2
    return x

l = list(map(times_two, [1, 2, 3]))
print(l)

# 输出
[2, 4, 6]


# 4. filter()

函数

  • 最大化代码重用
  • 最小代码冗余
  • 过程分解,降低代码逻辑复杂度

函数的定义

# def 函数名(参数) return 返回值
def function(args):
    print(args)
    return 'return'

# 函数实现找到两个string共同部分
def intersect(seq1, seq2):
    res = []
    for x in seq1:
        if x in seq2:
            res.append(x)
    return res

s1 = 'abcdfe'
s2 = 'bcd'
print(intersect(s1, s2))

# 使用推导实现
res = [x for x in s1 if x in s2]
print(res)

变量作用域

x = 55
def func():
    x = 99
    print(x)

print('Global x:', x)
print('Local x: ', end='')
func()

#输出 函数内逻辑没有改变外部变量(全局变量)
Global x: 55
Local x: 99
  • 使用全局变量用global标记
x2 = 55
def func2():
    global x2
    x2 = 99
    print(x2)

print('Global x2:', x2)
print('Local x2: ', end='')
func2()
print('Global x2:', x2)

#输出 函数逻辑改变了全局变量
Global x2: 55
Local x2: 99
Global x2: 99
# 其它作用范围
# Built-in : 作用域高于 global
# Enclousure : 封装域 nonlocal

# 内层函数不会修改外层 x
def func():
    x = 100
    def nested():
        # 如果使用nonlocal标记,则使用外层函数的x
        # nonlocal x
        x = 99
        print(x)
    nested()
    print(x)

参数传递方式

当参数向函数传递

  1. 不可变类型先做副本再传入,函数内不会影响原变量
  2. 可变类型传入地址引用,函数内的操作影响变量值
# 传入不可变类型,不改变原变量值
def change_num(x):
    x += 5

x = 5
print('x = {}'.format(x))
change_num(x)
print('x = {}'.format(x))

# 输出
x = 5
x = 5
# 传入可变类型,改变变量值
def change_list(l):
    l[0] = 'change'

l = [1, 2, 3]
print(l)
# 函数操作将改变l内的值,如不希望改变则传入l.copy() 或 l[:] 即可
change_list(l)
print(l)

# 输出
[1, 2, 3]
['change', 2, 3]
发布了45 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_22096121/article/details/103209886