迭代器与生成器

迭代器与生成器:

 

 

  1. 列表生成器:

    生成一个列表,可参考: http://www.cnblogs.com/ywhyme/p/7382132.html

    1. 普通

[x+1 for x in range(2,10,2)]

  1. 与函数一起使用

In [68]: def f(x):

...: return x**x

In [69]: [f(x) for x in range(2,10,2)]

Out[69]: [4, 256, 46656, 16777216]

  1. 使用匿名函数

In [74]: [(lambda i : i**i)(x) for x in range(2,10,2)]

Out[74]: [4, 256, 46656, 16777216]

 

  1. 使用map:

In [81]: a = map(f,range(2,10,2))

 

In [82]: list(a)

Out[82]: [4, 256, 46656, 16777216]

 

In [83]: a = map(f,[1,2,3])

 

In [84]: list(a)

Out[84]: [1, 4, 27]

 

  1. 生成器简介:
    1. 思考:在http://www.cnblogs.com/ywhyme/p/7382132.html中我将"[]"换成了"{}"并做了改变就成了字典,只换成"{}"变成了set:如下

In [87]: {x+1 for x in range(2,10,2)}

Out[87]: {3, 5, 7, 9}

        那么,我将"[]"换成"()",会是神马样子:

In [88]: (x+1 for x in range(2,10,2))

Out[88]: <generator object <genexpr> at 0x0082A570>

 

什么鬼,看官方解释;

A function which returns a generator iterator. It looks like a normal function except that it contains yield expressions for producing a series of values usable in a for-loop or that can be retrieved one at a time with the next() function.

Usually refers to a generator function, but may refer to a generator iterator in some contexts. In cases where the intended meaning isn't clear, using the full terms avoids ambiguity.

  1. 什么是生成器:

    恩,上面的就是解释.

  2. 为什么要用生成器.

    受到内存限制,列表容量肯定是有限的。

  3. 那么生成器里面存的是什么东西

    generator保存的是算法,也就是说,他并不是给你算好之后放那了,而是给你弄了个公式,每次用,每次再算

  4.  
  1. 生成器的使用
    1. 怎么创建一个生成器:

      两个方法:

              方法一: 就是刚才看到的那种:

(x+1 for x in range(2,10,2))

这样就生成了一个生成器                

        方法二:使用关键字yeild

Eg:

In [90]: def f():

...: yield

In [91]: f()

Out[91]: <generator object f at 0x00896C30>

补充:

返回值可不可以为空?......不是为None,是在最后写一个return,会不会有什么影响?

In [92]: def f():

...: return

...:

In [93]: f()

In [94]: print(f())

None

In [95]: def f():

...: return None

...:

In [96]: f()

In [97]: print(f())

None

In [104]: def f():

...: pass

...:

 

In [105]: print(f())

None

事实证明:返回的值写不写都是可以的,甚至你可以不写return,python会自动为其补上一个return

            

  1. 怎么调用生成器:

    方法一:使用next方法:

In [107]: a=(x+1 for x in range(5))

In [108]: a.__next__()

Out[108]: 1

In [109]: a.__next__()

Out[109]: 2

In [110]: a.__next__()

Out[110]: 3

In [111]: a.__next__()

Out[111]: 4

In [112]: a.__next__()

Out[112]: 5

In [113]: a.__next__()

--------------------------------------------------------------------------StopIteration Traceback (most recent call last)<ipython-input-113-73aa2c76d676> in <module>()

----> 1 a.__next__()

 

StopIteration:

In [114]: a=(x+1 for x in range(5))

In [115]: next(a)

Out[115]: 1

In [116]: next(a)

Out[116]: 2

In [117]: next(a)

Out[117]: 3

In [118]: next(a)

Out[118]: 4

In [119]: next(a)

Out[119]: 5

In [120]: next(a)

---------------------------------------------------------------------------

StopIteration Traceback (most recent call last)

<ipython-input-120-3f6e2eea332d> in <module>()

----> 1 next(a)

StopIteration:

最终抛出StopIteration:异常

方法二:使用for循环进行遍历:

In [126]: a=(x+1 for x in range(5))

 

In [127]: for v in a:

...: print(v)

...:

1

2

3

4

5

补充 for循环都做了什么事情:

(⊙o⊙)…好吧:我只在官方文档找到了这个:

The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the expression_list. The suite is then executed once for each item provided by the iterator, in the order returned by the iterator. Each item in turn is assigned to the target list using the standard rules for assignments (see Assignment statements), and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty or an iterator raises a StopIteration exception), the suite in the else clause, if present, is executed, and the loop terminates.

大致意思是说,先将其转化成一个iterator(迭代器),然后使用next方法取出,最后抛出StopIteration异常….

下图出自: http://www.cnblogs.com/yuanchenqi/articles/5769491.html

  1. 迭代器: iterator
    1. 定义:

An object representing a stream of data. Repeated calls to the iterator's __next__() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its __next__() method just raise StopIteration again. Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container.

协议:即必须满足有__next__(),和__iter__()两个方法

  1. 怎么生成一个迭代器:

    a.

生成器一般都是迭代器In [154]: a=(x+1 for x in range(2,10,2))

In [155]: isinstance(a,Iterator)

Out[155]: True

b.

可迭代对象通过调用__iter__()方法变成迭代器

In [165]: isinstance( "sdfsd".__iter__(),Iterator)

Out[165]: True

c.未完待续

class Test:

# def __init__(self,x):

# self.x=x

def __iter__(self):

return (x+1 for x in range(2,10,2))

 

  1. 使用方法:

    方法一:使用next()调用

    方法二:使用for遍历\

In [166]: next(a)

Out[166]: 's'

In [167]: for i in a:

...: print(i)

...:

d

f

s

d

 

  1.  
  1. 可迭代对象
    1. 什么是可迭代对象:

      有__iter__()方法的.

    2. 那些事可迭代的对象:

      Str ,list,tuple,dict,还有打开的文件句柄等

In [2]: f = open("hello.txt")

In [3]: f.__iter__()

Out[3]: <_io.TextIOWrapper name='hello.txt' mode='r' encoding='cp936'>

 

  1.  
  1. 容器:

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用 in , not in 关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特列并不是所有的元素都放在内存)在Python中,常见的容器对象有:

 

list, deque, ....

set, frozensets, ....

dict, defaultdict, OrderedDict, Counter, ....

tuple, namedtuple, …

str

七. 重点来了:

def a():

print("hello")

tem=yield 1

print("world")

print(tem)

yield 2

 

aa = a()

aa.send(None) #相当于next(aa)

aa.send("哈哈哈哈")

 

posted @ 2017-10-24 21:22  两只老虎111  阅读(237)  评论(0编辑  收藏  举报