首页 > 其他 > 详细

迭代器和生成器

时间:2019-05-02 21:20:59      阅读:124      评论:0      收藏:0      [点我收藏+]

一.   迭代器

 

  1.如何查看一个数据类型的所有方法?

#dir()可以查看数据类型所有可使用的方法
print(dir([1,2]))
print(dir({1,2}))
print(dir(‘‘))

#结果:
[__add__, __class__, __contains__, __delattr__, __delitem__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __getitem__, __gt__, __hash__, __iadd__, __imul__, __init__, __init_subclass__, __iter__, __le__, __len__, __lt__, __mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __reversed__, __rmul__, __setattr__, __setitem__, __sizeof__, __str__, __subclasshook__, append, clear, copy, count, extend, index, insert, pop, remove, reverse, sort]
[__and__, __class__, __contains__, __delattr__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __iand__, __init__, __init_subclass__, __ior__, __isub__, __iter__, __ixor__, __le__, __len__, __lt__, __ne__, __new__, __or__, __rand__, __reduce__, __reduce_ex__, __repr__, __ror__, __rsub__, __rxor__, __setattr__, __sizeof__, __str__, __sub__, __subclasshook__, __xor__, add, clear, copy, difference, difference_update, discard, intersection, intersection_update, isdisjoint, issubset, issuperset, pop, remove, symmetric_difference, symmetric_difference_update, union, update]
[__add__, __class__, __contains__, __delattr__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __getitem__, __getnewargs__, __gt__, __hash__, __init__, __init_subclass__, __iter__, __le__, __len__, __lt__, __mod__, __mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __rmod__, __rmul__, __setattr__, __sizeof__, __str__, __subclasshook__, capitalize, casefold, center, count, encode, endswith, expandtabs, find, format, format_map, index, isalnum, isalpha, isdecimal, isdigit, isidentifier, islower, isnumeric, isprintable, isspace, istitle, isupper, join, ljust, lower, lstrip, maketrans, partition, replace, rfind, rindex, rjust, rpartition, rsplit, rstrip, split, splitlines, startswith, strip, swapcase, title, translate, upper, zfill]

       2.通过观察我们不难发现,输出的结果里面都含有 __iter__这个方法(可迭代的都必须含有__iter__方法)

print(__iter__ in dir([1,2]))
print(__iter__ in dir({1,2}))
print(__iter__ in dir(‘‘))



#结果:
True
True
True

  3.什么是迭代器呢?

    请看下面的例子:

r=[].__iter__()
print(r)


#结果  : <list_iterator object at 0x000001C90B547358>

  返回乐意个有‘iterator的单词,这是什么意思呢?通过百度我们明白了它就是一个迭代器,

  我们通过调用列表的__iter__方法就得到了一个迭代器。

      4.那我们再看看迭代器里面都含有什么方法

r=[].__iter__()
print(dir(r))


#[‘__class__‘, ‘__delattr__‘, ‘__dir__‘, ‘__doc__‘, 
‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘,
‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__init_subclass__‘,
‘__iter__‘, ‘__le__‘, ‘__length_hint__‘, ‘__lt__‘,
‘__ne__‘, ‘__new__‘, ‘__next__‘, ‘__reduce__‘,
‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__setstate__‘,
‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘]

  这时我们发现里面有一个‘__next__‘方法。那它又有什么用处呢?

L=[1,2,3,4]
r=L.__iter__()
print(r.__next__())
print(r.__next__())
print(r.__next__())
print(r.__next__())



#1
#2
#3
#4

  每调用一次__next__方法都返回一个L列表里面的值,当列表里面的值输出完时,再调用__next__方法会报错

  5,好了,通过上面的例子我们可以了解到下面知识:

      1.迭代器一定可迭代(必须含有__iter__方法)可迭代不一定就是迭代器

      2.迭代器必定含有__iter__,__next__方法

二.   生成器

    生成器时在迭代器的基础上形成的(生成器必是迭代器)

   1.生成器函数

def genteater():
    print(a)
    yield 1


a=genteater()         #a只是一个生成器
print(a)




#<generator object genteater at 0x0000015792557048>

#generator就是生成器

  那如何打印函数里面的值呢?

def genteater():
    print(a)
    yield 1


a=genteater()         #a只是一个生成器
print(a.__next__())   #调用__next__ 方法

#a
#1

  如果你懂了上面的例子,那么请看下面

#调用__next__方法,每次只能执行一次yield,再次调用就从上一个yield哪里开始
def genteater():
    print(a)
    yield 1
    print(b)
    yield 2


a=genteater()         #a只是一个生成器
print(a.__next__())   #调用__next__ 方法
print(a.__next__())   

#a
#1
#b
#2

#当然我们也可以用for循环的发放循环生成器
def genteater():
    print(a)
    yield 1
    print(b)
    yield 2


a=genteater()         #a只是一个生成器
for i in a:
    print(i)


#a
#1
#b
#2

  2.生成器监听文件的例子:

#监听文件
def tail(file):
    f=open(file)
    while True:
        line=f.readline()
        if line.strip():
            yield line.strip()

g=tail(xiaowu)
for i in g:
    if python in i:
        print(****,i)

 

  send方法(可以向yield传值)

def generator():
    print(123)
    content=yield a
    print(***,content)
    print(456)
    yield b

g=generator()
print( g.__next__() )           #  ===print(g.send(None))
print(g.send(hello))          #和next用法大致一样,只是可以在获取下一个值的时候给上一个yield的位置传值
                                #send不能用在开头
#send实例
def func(a):
    def inner(*args,**kwargs):
        ret=a(*args,**kwargs)
        ret.__next__()
        return ret
    return inner
@func
def avg():
    sum=0
    count=0
    avg=0
    while True:
        num=yield avg
        sum+=num
        count+=1
        avg=sum/count

avg_1=avg()
ret=avg_1.send(10)
ret=avg_1.send(2)
print(ret)

  生成器面试题

       

#面试题1
def a():
    for i in range(4):
        yield i

b=a()

b1=(i for i in b)
b2=(i for i in b1)
print(list(b1))          #[0,1,2,3]
print(list(b2))          #[]   (g1已经空了,b2取不到值) 


#面试题2
def add(x,y):
    return x+y

def generator():
    for i in range(4):
        yield i
g=generator()

for a in [1,10]:
    g=(add(a,b) for b in g)
print(list(g))



#[20,21,23]
#其中

for a in [1,10]:
    g=(add(a,b) for b in g)
可以被替换成如下:
a=1
g=(add(a,b) for b in g)
a=10
g=(add(a,b) for b in g) # == g=(add(a,b) for b in (add(a,b) for b in generator() ))




即可以用下列代码表示
def add(x,y):
    return x+y

def generator():
    for i in range(4):
        yield i
g=generator()

a=1
g=(add(a,b) for b in g)
a=10
g=(add(a,b) for b in g)   # == g=(add(a,b) for b in (add(a,b) for b in generator() ))
print(list(g))

 


 

        

 

迭代器和生成器

原文:https://www.cnblogs.com/wm0217/p/10803330.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!