python中的yield和return

作者: Tim在路上 | 来源:发表于2018-10-05 08:46 被阅读1次

yield和return的区别与python中的generator和iterables相关,所以要了解其不同,首先要明白产生器和迭代器。

迭代器Iterables

迭代器就是你创建一个列表,你可以一个个的读取。

lists,strings,files 等都是可以迭代的,只要你可以用for ... in ...,但是你必须把它们的值放到内存里,当它们有很多值时就会消耗太多的内存.

lists = [1,2,3,4]
mys = [x*x for x in range(3)]
for i in mylist:
    print(i)

生成器generator

生成器也是迭代器,即迭代器包括生成器,但是你只能迭代他们一次,因为他们不是全部在内存中,他们只有在调用的时候在内存中生成。

mygenerator = (x*x for x in range(3))
for i in mygenerator:
    print(i)

但是生成器是用()而不是用[]
还有你不能用for i in mygenerator第二次调用生成器
因为其计算完就丢弃。

Yield

Yield的用法和关键字return差不多,下面的函数将会返回一个生成器

def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # 创建生成器
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)

当for语句第一次调用函数里返回的生成器对象,函数里的代码就开始运作,直到碰到yield,然后会返回本次循环的第一个返回值.所以下一次调用也将运行一次循环然后返回下一个值,直到没有值可以返回.

一旦函数运行并没有碰到yeild语句就认为生成器已经为空了.原因有可能是循环结束或者没有满足if/else之类的.
extend()是一个列表对象的方法,它可以把一个迭代对象添加进列表

生成器的好处

  • 你不需要读这个值两次
  • 你能得到许多孩子节点但是你不希望他们全部存入内存.
  • 这种方法之所以能很好的运行是因为Python不关心方法的参数是不是一个列表.它只希望接受一个迭代器,所以不管是strings,lists,tuples或者generators都可以!
  • 这种方法叫做duck typing,

控制迭代器穷尽

class Bank(): # 让我们建个银行,生产许多ATM
...    crisis = False
...    def create_atm(self):
...        while not self.crisis:
...            yield "$100"
>>> hsbc = Bank() # 当一切就绪了你想要多少ATM就给你多少
>>> corner_street_atm = hsbc.create_atm()
>>> print(corner_street_atm.next())
$100
>>> print(corner_street_atm.next())
$100
>>> print([corner_street_atm.next() for cash in range(5)])
['$100', '$100', '$100', '$100', '$100']
>>> hsbc.crisis = True # cao,经济危机来了没有钱了!
>>> print(corner_street_atm.next())
<type 'exceptions.StopIteration'>
>>> wall_street_atm = hsbc.create_atm() # 对于其他ATM,它还是True
>>> print(wall_street_atm.next())
<type 'exceptions.StopIteration'>
>>> hsbc.crisis = False # 麻烦的是,尽管危机过去了,ATM还是空的
>>> print(corner_street_atm.next())
<type 'exceptions.StopIteration'>
>>> brand_new_atm = hsbc.create_atm() # 只能重新新建一个bank了
>>> for cash in brand_new_atm:
...    print cash

迭代进阶 itertools

设置起点和步长

itertools.count(start=0, step=1)

from itertools import *

for i in izip(count(1), ['a', 'b', 'c']):
    print i

(1, 'a')
(2, 'b')
(3, 'c')

itertools.cycle(iterable)

from itertools import *

i = 0
for item in cycle(['a', 'b', 'c']):
    i += 1
    if i == 10:
        break
    print (i, item)

(1, 'a')
(2, 'b')
(3, 'c')
(4, 'a')
(5, 'b')
(6, 'c')
(7, 'a')
(8, 'b')
(9, 'c')

itertools.repeat(object[, times])

from itertools import *

for i in repeat('over-and-over', 5):
    print i

over-and-over
over-and-over
over-and-over
over-and-over
over-and-over

itertools.chain(*iterables)
将多个迭代器作为参数, 但只返回单个迭代器, 它产生所有参数迭代器的内容, 就好像他们是来自于一个单一的序列.

from itertools import *

for i in chain([1, 2, 3], ['a', 'b', 'c']):
    print i
1
2
3
a
b
c

itertools.groupby(iterable[, key])

from itertools import groupby
qs = [{'date' : 1},{'date' : 2}]
[(name, list(group)) for name, group in itertools.groupby(qs, lambda p:p['date'])]

Out[77]: [(1, [{'date': 1}]), (2, [{'date': 2}])]


>>> from itertools import *
>>> a = ['aa', 'ab', 'abc', 'bcd', 'abcde']
>>> for i, k in groupby(a, len):
...     print i, list(k)
...
2 ['aa', 'ab']
3 ['abc', 'bcd']
5 ['abcde']

itertools.permutations

horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)
<itertools.permutations object at 0xb754f1dc>
>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
 (1, 2, 4, 3),
 (1, 3, 2, 4),
 ...

更多的见
(http://www.wklken.me/posts/2013/08/20/python-extra-itertools.html)

相关文章

  • python中的yield和return

    yield和return的区别与python中的generator和iterables相关,所以要了解其不同,首先...

  • yield(对比return)

    带有 yield 的函数在 Python 中被称之为 generator(生成器),return和yield的形式...

  • python-复盘-yield & return区别

    python-复盘-yield & return区别

  • python中的yield与return

    yield与return的功能都是返回程序执行结果,但是yield返回执行结果并不中断程序执行,return在返回...

  • yield和生成器是什么?

    yield在Python里面也是一个较难懂的奇技淫巧,和return类似,但是和return有天差地别的不同 在函...

  • koa 和 ES6

    构造器的写法 yield的作用yield类似return,但是在一般函数中,return只能一次。但是yield在...

  • yield和return

    1、.print并不会阻断程序的执行,就不用多说了。 2、func2()方法中的循环执行第一次就被return结束...

  • 对于字体裁剪生僻字的做法

    1)对于字体裁剪生僻字的做法 2)协程中yield return CoFunction()和yield retur...

  • python yield return 区别

    yieldyield是用于生成器。什么是生成器,你可以通俗的认为,在一个函数中,使用了yield来代替return...

  • Python关键字yield的含义

    yield 主要用在Generator中,含义和return非常类似,唯一的区别是yield是lazy的,而ret...

网友评论

    本文标题:python中的yield和return

    本文链接:https://www.haomeiwen.com/subject/vtltaftx.html