学习笔记☞python 基础☞迭代器&生成器&字节串&和字节数组 ☞python3


迭代器 Iterator 和 生成器 Generator


什么是迭代器:

    迭代器是访问可迭代对象的一种方式,用迭代器可以访问可迭代对象
    迭代器是指iter(可迭代对象)返回的对象
    迭代器可以用next(it)函数获取可迭代对象的数据
    
迭代器函数iter和next
    iter(iterable)   从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象
    next(iterable)   从迭代器iterable中获取下一个记录.如果无法获取下一条记录,则触发StopIterator异常

迭代器说明:
    迭代器只能往前取值,不会后退
    用iter函数可以返回一个可迭代对象的迭代器
    
示例:
L = [2, 3, 5, 7]
it = iter(L)  # 用iter返回一个迭代器用it绑定
next(it)  # 2    #用next(it)用迭代器来获取L中的元素
next(it)  # 3
next(it)  # 5
next(it)  # 7
next(it)  # StopIterator    #通知next调用者,已无数据
#用迭代器获取range对象的数据
>>> it = iter(range(1, 10, 3))
>>> next(it)
1
>>> next(it)
4
>>> next(it)
7
>>> next(it)
StopIteration

示例:
L = [2, 3, 5, 7]
# 用for循环访问可迭代对象中的数据
for x in L:
    print(x)
print('=*= ' * 10+'=*=')

# 用while循环访问可迭代对象中的数据
# 第一步,让L给我们一个迭代器
it = iter(L)
# 第二步,循环用it迭代器去获取L中的数据,直到StopIteration为止
while True:
    try:
        x = next(it)
        print(x)
    except StopIteration:
        break
    
练习:
    已知有一个集合:
    s=('工商银行','建设银行','中国银行','农业银行')
    1.用for语句遍历集合中的元素并打印
    2.将上面for语句改成while语句实现上面同样的功能
s = ('工商银行', '建设银行', '中国银行', '农业银行')
for i in s:
    print(i)

print('=*= ' * 10 + '=*=')
def iterator(s):
    it=iter(s)
    while True:
        try:
            i=next(it)
            print(i)
        except:
            break
if __name__ == '__main__':
    s = ('工商银行', '建设银行', '中国银行', '农业银行')
    iterator(s)
    


生成器 generator(python2.5及之后版本)


什么是生成器:
    生成器是能够动态提供数据的对象,生成器对象也是可迭代对象

生成器有两种:
    生成器函数
    生成器表达式

生成器函数定义:
    含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象
    yield 翻译为(产生或生成)
    
yield语句
    语法:
        yield 表达式
    说明:
        yield 用于def函数中,目的是将此函数作为生成器函数使用
        yield 用来生成数据,提供next(it)函数使用

示例:
    写一个生成器函数my_integer(n)生成1到n的整数:
def my_integer(n):
    i=1#先初始化变量i将其设置为起始数
    while i <n:#循环判断是否已到终止点,如果未到则生成
        yield i#生成整数
        i+=1#控制循环条件
if __name__ == '__main__':
    for i in my_integer(100):
        print(i)                
练习:
    
'''
写一个函数,myodd(start,stop)
用于生成start开始stop(不含)结束的所有奇数
L=[x for x in myodd(1,10)]
print(L)#[1,3,5,7,9]
for x in myodd(10,20):
    print(x) #11,13,15,17,19
'''


def myodd(start, stop):
    while start < stop:
        if start % 2:  # 等同于start%2==1
            yield start
        start += 1


if __name__ == '__main__':
    L = [x for x in myodd(1, 10)]
    print(L)  # [1,3,5,7,9]
    for x in myodd(10, 20):
        print(x)  # 11,13,15,17,19

生成器表达式:

    语法:
        (表达式 for 变量 in 可迭代对象 [if 真值表达式])
        注: []内的if部分可以省略
    作用:
        用推导式形式生成一个生成器
    示例:
gen = (x ** 2 for x in range(1, 5))
it = iter(gen)
next(it)  # 1
next(it)  # 4
next(it)  # 9
next(it)  # 16
next(it)  # StopIteration
        
迭代工具函数:
    迭代工具函数的作用是生成一个个性化的可迭代对象
zip(iter1[,iter2, ...])
    返回一个zip对象,此对象用于生成一个元组,此元组的个数是由最小的可迭代对象决定的,元组内容是可迭代对象iter1和iter2中元素的足额
enumerate(iterable[,start])
    生成带索引的枚举对象,返回的迭代类型为索引-值对(index-value)对,默认索引从零开始,也可以用start指定

示例:
#zip示例一
numbers = [10086, 10000, 10010, 95588]
name = ['中国移动', '中国电信', '中国联通']

for t in zip(numbers, name):
    print(t)
# print(dict(zip(name,numbers )))

#zip示例二
# 此示例示意zip函数的内部实现方法
def myzip(iter1, iter2):
    it1 = iter(iter1)
    it2 = iter(iter2)
    try:
        while True:

            a = next(it1)
            b = next(it2)
            yield (a, b)
    except:
        pass


numbers = [10086, 10000, 10010, 95588]
name = ['中国移动', '中国电信', '中国联通']

for t in myzip(numbers, name):
    print(t)

#zip示例三
numbers = [10086, 10000, 10010, 95588]
name = ['中国移动', '中国电信', '中国联通']

for t in zip(range(1,1111),numbers, name):
    print(t)
# print(dict(zip(name,numbers )))

#enumerate示例-1
# 此示例示意enumerate的用法
names = ['中国移动', '中国电信', '中国联通']
for t in enumerate(names):
    print(t)
print('*'*20)
for t in enumerate(names,1):
    print(t)

#enumerate示例-2
# 此示例示意enumerate的用法
names = ['中国移动', '中国电信', '中国联通']

for a,t in enumerate(names,1):
    print('序号',a,'------>',t)
#等同于
it=iter(enumerate(names,1))
while True:
    try:
        k,n=next(it)
        print('序号',k,'------>',n)
    except StopIteration:
        break

练习:
    写一个程序,读入任意行的文字数据,当输入空行时结束输入
    打印带行号的输入结果:
    如:
    请输入:hello<回车>
    请输入:tarena<回车>
    请输入:bye<回车>
    请输入:<回车>
    输出如下;
    第1行:hello
    第2行:tarena
    第3行:bye
    
def input_text():
    '''读入键盘输入的文本数据,形成列表后返回'''
    L = []
    while True:
        str_ = input('请输入:')
        if not str_:
            break
        L.append(str_)
    return L


def output_text(L):
    for t in enumerate(L, 1):
        print('第%d行:%s' % t)


if __name__ == '__main__':
    text_L = input_text()
    output_text(text_L)
          

字节串和字节数组

字节串(也叫字节序列) bytes

    作用:
        存储以字节为单位的数据
    说明:
        字节串是不可改变的序列
        字节是0~255之间的整数
创建空字节串的字面值
    b''
    b""
    b''''''
    b""""""
创建非空字节串的字面值
    B=b'hello'
    B=b"hello"
    B=b'''abcd'''
    B=b"""abcd"""
    B=b'abc\n123'
    B=b'\x41\x42'
字节串的构造函数:
    bytes()                            生成一个空的字节串 等同于b''
    bytes(整数可迭代对象)             用可迭代对象初始化一个字节串
    bytes(整数n)                     生成n个值为0的字节串
    bytes(字符串,encoding='utf-8')     用字节串的转换编码生成一个字节串
    
bytes 的运算:
    + += * *=
    < <= > >= == !=
    in / not in
    索引和切片
in / not in 示例:
B=b'ABCDE'
0x41 in B # True
用于序列的函数:   

len() max min sum() any() all() 都可以用于字节串

序列的方法:
    详见:
        help(bytes)

bytes与str的区别:
    bytes     存储字节(0~255)
    str     存储字符
bytes与str转换
        编码(encode)
    str ---------> bytes
        b=s.encode(encoding='utf-8')
        
          解码(decode)
    bytes -------------> str
        s=b.decode(encoding='utf-8')
例:
   
b='你好'.encode('utf-8')
print(b)        # b'\xe4\xbd\xa0\xe5\xa5\xbd'
s=b.decode('utf-8')
print(s)        # '你好'

字节数组 bytearray

    可变的字节序列
创建函数 bytearray
    bytearray()        创建空字节数组
    bytearray(整数)
    bytearray(整形可迭代对象)
    bytearray(字符串,encoding='utf-8')
        
操作:
    + += * *=
    < <= > >= == !=
    in / not in
    索引 index / 切片 slice
    (字节数组可以索引和切片赋值,赋值规则同列表的索引和切片赋值相同)
例:
ba = bytearray(b'abcdefg')
ba[0] = 0x41        #ba = bytearray(b'Abcdefg')
ba[1::2] = bytearray(b'BDF')  #修改bdf为大写
bytearray 的方法:
BA 代表bytearray
 
BA.clear()
请空字节数组
 BA.append()
追加一个字节(n0~255的整数)
BA.remove(value)
删除第一个出现的字节,如果没有出现,则触发BalueError 错误
BA.reverse()
字节的顺序反转
BA.decode(encoding='utf-8')
bytearray 转换为字符串
BA.find(sub[, start[, end]])
查找sub子字节数
>>> BA=bytearray(b'ABCD')
>>> BA.append('\x45')
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: an integer is required
>>> BA.append(0x45)
>>> BA
bytearray(b'ABCDE')
>>> BA.remove(0x41)
>>> BA
bytearray(b'BCDE')

练习:
    1.用生成器函数生成斐波那契数列的前n个数
        1 1 2 3 5 8 13 ...
        def fibonacci(n):
            ...
            yield ..
        1) 输出前 20 个数
        2) 求前 30 个数的和
    2.写程序打印杨辉三角(只打印6层)





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值