python迭代器,生成器,列表推导式(开放封闭原则,locals,globals)


迭代器
可迭代对象
s1 = '123'
for i in s1:
    print(i)
int  object is not iterable
for i in 123:
    print(i)
内部含有__iter__方法的就是可迭代对象,遵循可迭代协议
dir
print(dir('123'))  # '__iter__'
print('__iter__' in dir([1, 2, 3]))
print('__iter__' in dir({'name':'aaa'}))
print('__iter__' in dir({'name'}))
print('__iter__' in dir((1, 2, 3)))
print('__iter__' in dir(1))  # False
print('__iter__' in dir(True))  # False
可迭代对象通过.__iter__()可以转换成迭代器,满足迭代器协议。
内部含有__iter__ 且 __next__方法的就是迭代器。
l = [1, 2, 3]
l_obj = l.__iter__()
print(l_obj)
迭代器的取值两种方法:
方法一:__next__()
print(l_obj.__next__())
print(l_obj.__next__())
print(l_obj.__next__())
print(l_obj.__next__())
方法二 for循环
for i in l_obj:
    print(i)
print('__next__' in dir(l_obj))
第二种判断方式:
from collections import Iterable
from collections import Iterator
print(isinstance('123', Iterable))
print(isinstance('123', Iterator))
实际上可迭代对象是不可以一个一个的一次取值的,因为他没有__next__方法。
for循环提供一个机制:
1,将可迭代对象转化成迭代器。
2,利用__next__进行取值。
3,用try异常处理方法防止报错。
l = [1, 2, 3, 4, 5]
l_obj = l.__iter__()
while True:
    try:
        print(l_obj.__next__())
    except Exception:
        break
迭代器:
1,节省内存。
2,满足惰性机制。
3,取值过程不可逆(一条路走到黑)。
生成器本质也是迭代器,生成器是自己用Python写的迭代器。
1,通过生成器函数构建。
2,通过生成器推导式构建。
def func1():
    print(666)
    return 222
ret = func1()
print(ret)

def func1():
    print(11)
    print(333)
    yield 222
    print(666)
    yield 777
g_obj = func1()  # 生成器对象 generator object
print(g_obj.__next__())
print(g_obj.__next__())

def cloth1():
    for i in range(1,10001):
        print('衣服%s' % i)
# cloth1()


def cloth2():
    for i in range(1,10001):
        yield '衣服%s' % i

g = cloth2()
for i in range(1,51):
    print(g.__next__())

for i in range(1, 151):
    print(g.__next__())
next  send
def func1():
    count = yield 222
    print(count)
    yield 777
    yield 888
g_obj = func1()  # 生成器对象 generator objectprint(g_obj.__next__())#222
print(g_obj.send('wusir'))#wusir  777,必须给yield赋值才能传值成功
1,send 具有next功能。
2,send 可以给上一个yield传值。
3, 第一个取值不能使用send.
4,最后一个yield不会得到send的值。
列表推导式:
能用列表推导式完成的,用python代码都可以完成。
用一句话构建一个你想要的列表。
优点:简单,稍微难理解。
缺点: 不能用debug。
li = []
for i in range(1, 12):
    li.append(i)
print(li)

li = [i for i in range(1, 12)]
[ 变量(加工后的变量) for 变量 in 可迭代对象 ]  遍历模式
print(li)
li = []
for i in range(1, 12):
    li.append('python第%s人 % i)
print(li)

li = ['aa', 'bb', 'cc', 'dd', 'ee']
li = ['python第%s人' % i for i in range(1, 12)]
print(li)
l2
= [i+'_NB' for i in li] print(l2)
[ 变量(加工后的变量) for 变量 in 可迭代对象 ]  遍历模式
[ 变量(加工后的变量) for 变量 in 可迭代对象 if 判断] 筛选模式
l1 = [i for i in range(1, 101) if i % 2 == 0]
print(l1)
1,筛选,100以内所有的奇数。
l2 = [i for i in range(1, 101) if i % 2 == 1]
l2 = [i for i in range(1, 101, 2)]
print(l2)
2,10以内所有数的平方。 [1,4,9,16.。。100]
print([i*i for i in range(1, 11)])
3,将100以内所有内被三整除的数留到列表中。
print([i for i in range(1,101) if i % 3 == 0])

g = (i*i for i in range(1, 11))
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
for i in g:
    print(i)
列表推导式 简单明了,但是占内存
生成器表达式 节省内存,不易看出。
30以内所有能被3整除的数的平方
print([i*i for i in range(1, 31) if i % 3 ==0])

names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
l3 = [ name for i in names for name in i if name.count('e') == 2]
print(l3)

mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency)
tast
用列表推导式做下列小题
(1)过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
l=['jl','mklk','k','buguhhji']
print([i.upper() for i in l if len(i)>3])
(2)求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元祖列表
l1=[]
l2=[]
for i in range(0,6):
    if i%2==0:
        l1.append(i)
    else:
        l2.append(i)
print(l1,l2)
l3=[]
for i in l1:
    for j in l2:
        l3.append((i,j))
print(l3)

print([(i,j) for i in range(0,6) for j in range(0,6) if i%2==0 and j%2==1])
print([(i,j) for i in range(0,6) if i%2==0 for j in range(0,6) if j%2==1])
(3)求M中3,6,9组成的列表M = [[1,2,3],[4,5,6],[7,8,9]]
M = [[1,2,3],[4,5,6],[7,8,9]]
print([[i[2],i[2],i[2]] for i in M])#错误,曲解了for 循环的意义
print( [i[2] for i in M])
print([[i-2,i-1,i]for i in range(3,10,3)])
(4)求出50以内能被3整除的数的平方,并放入到一个列表中。
print([i**2 for i in range(51)if i%3==0])
(5)构建一个列表:['python第1人', 'python第2人', 'python第3人', 'python第4人', 'python第6人']
print(['python 第%s 人' % i for i in range(1,7 if i != 5])#一定要细心,没有5
(6)构建一个列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
print([(i,i+1) for i in range(0,6)])
(7)构建一个列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print([i for i in range(19)if i%2==0])
(8)有一个列表l1 = ['aa', 'bb', 'cc', 'dd']将其构造成这种列表
['aa0', 'bb1', 'cc2', 'dd3']
l1 = ['aa', 'bb', 'cc', 'dd']
print([i+str(l1.index(i)) for i in l1])#str(l1.index(i)数字转化为字符串
(9)有以下数据类型:
x = {
    'name':'alex',
    'Values':[
         {'timestamp':1517991992.94,
         'values':100,},
        {'timestamp': 1517992000.94,
        'values': 200,},
        {'timestamp': 1517992014.94,
         'values': 300,},
        {'timestamp': 1517992744.94,
         'values': 350},
        {'timestamp': 1517992800.94,
         'values': 280}
      ],}
将上面的数据通过列表推导式转换成下面的类型:[[1517991992.94, 100],
[1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350],
[1517992800.94, 280]]
li = [['{},{}'.format(j['timestamp'], j['values'])] for i in x if i == 'Values' for j in x[i]]
print(li)

print([[i[0],i[1]] for i in 'Values'])#字典取值不明确
print([[i['timestamp'],i['values']] for i in x['Values']])

 总结

迭代器
 可迭代对象:内部含有__iter__
    迭代器:可迭代对象.__iter__()
    迭代器:内部含有__iter__且__next__
        判断 __iter__ 在不在dir(对象中)
        isinstance()
        节省内存。
        惰性机制。
        单向不可逆。
    for循环的机制:
        while
        pass


    可迭代对象
    迭代器
    两者区别
    模拟for循环机制
生成器
本质上是迭代器,用python代码构建的。
    生成器定义
    生成器的写法
    yield
    send

posted @ 2018-05-19 23:47  老虎死了还有狼  阅读(216)  评论(0编辑  收藏  举报