代码之家  ›  专栏  ›  技术社区  ›  173210

从Python中的生成器中删除重复代码

  •  3
  • 173210  · 技术社区  · 10 年前
    def generator():
        for i in range(10):
            yield "foo" + "baz"
    
        for i in range(10):
            yield "bar" + "baz"
    

    我想让代码如下:

    def baz(s):
        for i in range(10):
            yield s + "baz"
    
    def generator():
        baz("foo")
        baz("bar")
    

    然而,此代码的行为不同。

    如何消除重复代码,包括 yield 在发电机中?

    P.S.我找到了 yield from 。这正是我想要的,但我的项目是Python 2.7。

    3 回复  |  直到 10 年前
        1
  •  1
  •   Martin Evans    10 年前

    你可以重新编码使用 itertools 如下:

    from itertools import repeat, chain
    
    def generator():
        for i in chain(repeat('foobaz', 10), repeat('barbaz', 10)):
            yield i
    
    for x in generator():
        print x
    

    给你:

    foobaz
    foobaz
    foobaz
    foobaz
    foobaz
    foobaz
    foobaz
    foobaz
    foobaz
    foobaz
    barbaz
    barbaz
    barbaz
    barbaz
    barbaz
    barbaz
    barbaz
    barbaz
    barbaz
    barbaz
    

    或者作为一个简单的列表:

    from itertools import repeat, chain
    
    def generator():
        return list(chain(repeat('foobaz', 10), repeat('barbaz', 10)))
    
    print generator()
    

    给:

    ['foobaz', 'foobaz', 'foobaz', 'foobaz', 'foobaz', 'foobaz', 'foobaz', 'foobaz', 'foobaz', 'foobaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz', 'barbaz']
    
        2
  •  0
  •   Selcuk    10 年前

    你可以这样重写:

    def baz(s):
        for i in range(10):
            yield s + "baz"
    
    def generator():
        for s in ["foo", "baz"]:
            for b in baz(s):
                yield b
    
        3
  •  0
  •   Community Mohan Dere    9 年前

    马丁的回答, https://stackoverflow.com/a/35286012/901925 可以转换为:

    def baz(s):
        for i in range(4):yield s+'baz'
    
    def g2():
        return itertools.chain(baz('foo'),baz('bar'))
    
    In [411]: list(g2())
    Out[411]: 
    ['foobaz',
     'foobaz',
     'foobaz',
     'foobaz',
     'barbaz',
     'barbaz',
     'barbaz',
     'barbaz']