【问题标题】:Python 3 -- [s for s in subsets(S)] and yieldPython 3 -- [s for s in subsets(S)] 和产量
【发布时间】:2012-02-01 10:52:27
【问题描述】:

这是我在互联网上找到的一些代码,并没有太多解释。我只是好奇它是如何工作的。我不完全理解yield[s for s in subsets(S)] 部分。任何见解将不胜感激!

def subsets(aList):

       if aList ==[]:   # base case
          yield []
       else:
          first = aList[0]
          rest  = aList[1:]
          for ss in subsets(rest):  # include first or don't in each
              yield ss                   # subset of rest
              yield [first]+ss

print ("\n testing subsets")
S = ['A','B','C','D','E']

ss = [s for s in subsets(S)]

print ("The subsets of",S,"are:")

print (ss)

【问题讨论】:

    标签: python python-3.x yield subset


    【解决方案1】:

    subsets 是一个生成器:当您调用它时,您会创建一个可以迭代的对象。每次迭代向它请求另一个值时,它都会运行到下一个yield 语句,并生成该值。它也是递归的,所以当你用五个项目运行它时,它会在最后四个上调用自己,依此类推。

    所以,如果它被传递了['A'],它会创建第二个生成器,它会传递一个空列表[]。那只会产生一个空列表,然后完成。主生成器将接收它,生成它(yield ss),然后是yield [first]+ss,这将是['A']。总结果:[[], ['A']]

    [s for s in subsets(S)] 是一个列表理解。相当于:

    ss = []
    for s in subsets(S)
        ss.append(s)
    

    在这种情况下,这有点多余 - 您可以通过 list(subsets(S)) 来实现相同的目标。当您想要对一组对象中的每一个执行某些操作或想要过滤它们时,可以使用列表推导式。

    【讨论】:

      【解决方案2】:

      理解yield 的方法是想象它只是一个return 语句,加上下一次调用函数时,从yield 语句继续执行。当没有更多的收益时,会引发StopIteration 异常。

      一个更简单的例子应该可以解决问题:

      >>> def foo():
      ...     for i in range(3):
      ...         yield i
      ... 
      >>> x = foo()
      >>> x
      <generator object foo at 0x7f0cd5c30780>
      >>> x.next()
      0
      >>> x.next()
      1
      >>> x.next()
      2
      >>> x.next()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      StopIteration
      >>>
      

      您可以像使用可迭代对象一样使用生成器,因为 for 循环只是在内部捕获并处理 StopIteration 异常:

      >>> x = foo()
      >>> for i in x:
      ...     print i
      ... 
      0
      1
      2
      >>>
      

      至于获取子集,有一种更简单的方法!
      看看下面的食谱:

      >>> from itertools import chain, combinations
      >>>
      >>> def powerset(iterable):
      ...     s = list(iterable)
      ...     return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
      >>>
      >>> S = ['A','B','C']
      >>> list(powerset(S))
      [(),
       ('A',),
       ('B',),
       ('C',),
       ('A', 'B'),
       ('A', 'C'),
       ('B', 'C'),
       ('A', 'B', 'C')]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-14
        • 1970-01-01
        • 2014-02-14
        • 2014-11-02
        • 1970-01-01
        • 2011-10-31
        • 1970-01-01
        • 2015-06-10
        相关资源
        最近更新 更多