【问题标题】:Is there any way to shorten this Python generator expression?有没有办法缩短这个 Python 生成器表达式?
【发布时间】:2013-04-24 23:55:33
【问题描述】:

我需要构建一个生成器,并且我正在寻找一种方法将这个 for 循环缩短为一行。我尝试枚举,但没有奏效。

counter=0
for element in string:
    if function(element):
        counter+=1
        yield counter
    else:
        yield counter

【问题讨论】:

  • 您是否缺少counter=0,或者这应该是外部代码中counter 的闭包?
  • 什么版本的 Python?
  • 不,我最初排除了它,但我只是包含它。

标签: python list for-loop generator list-comprehension


【解决方案1】:
counter=0
for element in string:
    counter+=bool(function(element))
    yield counter

(是的,将布尔值添加到 ints 就像 True1False0)。

仅当function() 可以具有除TrueFalse10 之外的返回值时,才需要调用bool()

【讨论】:

    【解决方案2】:

    首先,您可以将字符串转换为function 返回值上的迭代器:

    truths = (function(x) for x in string)
    

    然后您可以将它们映射到 0 和 1:

    onesandzeroes = (1 if function(x) else 0 for x in string)
    

    然后accumulate他们:

    running = itertools.accumulate(1 if function(x) else 0 for x in string)
    

    如文档所述,accumulate 是在 Python 3.2 中添加的。如果您使用的是 2.x,则可以从文档中复制并粘贴“等效于”配方。 (如果您使用的是 3.0-3.1,您也可以这样做,但实际上,在这种情况下,只需升级即可。)

    【讨论】:

      【解决方案3】:

      如果你使用的是 Python 3,你可以这样做:

      from itertools import accumulate
      
      yield from accumulate(1 if function(x) else 0 for x in string)
      

      虽然我会使用Simeon Visser's answer。虽然这段代码可能很短,但目前还不清楚代码的作用。

      【讨论】:

      • @jamylak:最后你没有留下counter 变量。
      • 除非function 明确返回0 和1,否则这将不起作用。如果它返回,例如None 或字符串,您将得到TypeErrors。即使它返回TrueFalse,第一个值也将是False 而不是0
      • 我不确定“我假设 accumulate 返回一个布尔值”是什么意思。它返回一个迭代器。它是你给它的任何可添加类型的迭代器(或者,更确切地说,是添加你给它的任何类型的结果——不完全一样,因为,例如,False+True == 1,或者,在旧的 Python 中,(1<<31) + (1<<31) = (1L<<32) )。
      • @abarnert:对不起,accumulate 应该是 function
      • @Blender:那么它仍然是错误的,因为正如我之前解释的,你产生的第一个值将是False,而不是0
      【解决方案4】:

      您可以将其缩短为:

      counter=0
      for element in string:
          if function(element):
              counter+=1
          yield counter
      

      【讨论】:

      • 我需要保持一个运行计数,所以我也需要使用 else 语句来让步。
      • @garlfd:这仍然会产生字符串中的每个元素,它只会为某些元素更新它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      • 2019-12-01
      • 2020-11-17
      • 1970-01-01
      • 2022-01-05
      • 2022-11-18
      • 2019-12-23
      相关资源
      最近更新 更多