【问题标题】:Multiple statements in list compherensions in Python?Python中列表组合中的多个语句?
【发布时间】:2010-12-27 04:03:57
【问题描述】:

是否有可能有类似的东西:

list1 = ...

currentValue = 0
list2 = [currentValue += i, i for i in list1]

我试过了,但没用?写这些的正确语法是什么?

编辑:打印语句就是一个例子。实际上我是在循环外增加一个值。

【问题讨论】:

  • 普通的for语句有什么问题?当你有一个非常好的陈述时,为什么还要为此烦恼呢?你想达到什么目的?
  • 没什么,只是想看看 Python 中的 list compherensions 是否可行。

标签: python list-comprehension


【解决方案1】:

语句不能进入 Python 中的表达式;这是一种故意用语言设计的复杂功能。对于这个问题,请尝试使用确实进入语言的复杂功能:生成器。观看:

def total_and_item(sequence):
    total = 0
    for i in sequence:
        total += i
        yield (total, i)

list2 = list(total_and_item(list1))

生成器对目前看到的项目保持运行记录,并将其作为每个项目的前缀,就像您的示例尝试做的那样。当然,一个简单的循环可能更简单,它在顶部创建一个空列表,并且只调用 append() 很多! :-)

【讨论】:

  • +1 表示语句被排除在表达式之外(更不用说 multiple 语句了 :-),以及更明确的方法的建议。
【解决方案2】:

我不太确定您要做什么,但可能类似于

list2 = [(i, i*2, i) for i in list1]
print list2

列表推导式中的语句必须是单个语句,但您始终可以将其设为函数调用:

def foo(i):
    print i
    print i * 2
    return i
list2 = [foo(i) for i in list1]

【讨论】:

    【解决方案3】:

    正如pjz所说,你可以使用函数,所以在这里你可以使用闭包来跟踪计数器值:

    # defines a closure to enclose the sum variable
    def make_counter(init_value=0):
        sum = [init_value]
        def inc(x=0):
            sum[0] += x
            return sum[0]
        return inc
    

    然后你用 list1 做你想做的事:

    list1 = range(5)  # list1 = [0, 1, 2, 3, 4]
    

    现在只有两行,我们得到 list2:

    counter = make_counter(10)  # counter with initial value of 10
    list2 = reduce(operator.add, ([counter(x), x] for x in list1))
    

    最后,list2 包含:

    [10, 0, 11, 1, 13, 2, 16, 3, 20, 4]
    

    这是你想要的,你可以通过一次调用获得循环后计数器的值:

    counter()  # value is 20
    

    最后,你可以用任何你想要的操作来替换闭包,这里我们有一个增量,但这完全取决于你。 另请注意,我们使用 reduce 来展平 list2,这个小技巧要求您在使用 reduce 调用该行之前导入 operator

    import operator
    

    【讨论】:

      【解决方案4】:

      这是来自another question的示例:

      [i for i,x in enumerate(testlist) if x == 1]
      

      枚举生成器返回一个进入 i,x 的 2 元组。

      【讨论】:

        【解决方案5】:

        首先,您可能不想使用print。它不返回任何内容,因此如果您只想打印内容,请使用传统的for 循环。您正在寻找的是:

        >>> list1 = (1,2,3,4)
        >>> list2 = [(i, i*2) for i in list1] # Notice the braces around both items
        >>> print(list2)
        [(1, 2), (2, 4), (3, 6), (4, 8)]
        

        【讨论】:

          【解决方案6】:

          在列表理解中调用打印是一件奇怪的事情。如果您向我们展示您想要的输出,而不仅仅是不起作用的代码,将会有所帮助。

          这里有两个猜测。无论哪种方式,重要的一点是列表推导式中的值语句必须是 single 值。您不能一次插入多个项目。 (如果这就是您要执行的操作,请跳至第二个示例。)

          list1 = [1, 2, 3]
          list2 = [(i, i*2, i) for i in list1]
          # list2 = [(1, 2, 1), (2, 4, 2), (3, 6, 3)]
          

          获取平面列表:

          list1 = [1, 2, 3]
          tmp = [(i, i*2) for i in list1]
          list2 = []
          map(list2.extend, tmp)
          # list2 = [1, 2, 1, 2, 4, 2, 3, 6, 3]
          

          编辑: 在列表理解的中间增加一个值仍然很奇怪。如果你真的需要这样做,你最好只写一个常规的 for 循环,并在你去的时候附加值。在 Python 中,像这样的聪明几乎总是被贴上“unpythonic”的标签。如果你必须这样做,但你会在这样的论坛中得到无休止的抨击。 ;)

          【讨论】:

          • 谢谢,基本上我需要在列表理解之外增加一个值。
          • 你能把你正在做的事情写成一个“for item in list1”循环吗?这样会更容易确定它是否适合列表理解。
          【解决方案7】:

          对于您编辑的示例:

          currentValue += sum(list1)
          

          或:

          for x in list1:
              currentValue += x
          

          列表推导很棒,我喜欢它们,但不起眼的 for 循环并没有错,你不应该害怕使用它 :-)

          编辑:“但是如果我想增加与收集的值不同的值怎么办?”

          嗯,你想增加什么?你拥有 python 的全部力量!

          按 x 平方递增?

          for x in list1:
              currentValue += x**2
          

          x 的某个函数的增量及其在列表中的位置?

          for i, x in enumerate(list1):
              currentValue += i*x
          

          【讨论】:

          • 但是如果我想增加与收集的值不同的值怎么办?
          【解决方案8】:

          为什么要创建重复列表。似乎列表理解所做的只是对内容求和。

          为什么不只是。

          list2 = list(list1)   #this makes a copy
          currentValue = sum(list2)
          

          【讨论】:

            【解决方案9】:

            你不能做多个语句,但你可以做一个函数调用。要执行您似乎想要的上述操作,您可以执行以下操作:

            list1 = ...
            list2 = [ (sum(list1[:i], i) for i in list1 ]
            

            一般来说,由于列表推导是 python 的“功能”部分的一部分,因此您只能使用...函数。其他人建议您可以根据需要编写自己的函数,这也是一个有效的建议。

            【讨论】:

            • 这不会生成 n 个列表,其中 n 是第一个列表的长度?结果,如果列表包含数千个元素,可能会花费太多时间。
            • 当然,但效率不是目标——使用列表理解才是。您的生成器解决方案显然要高效得多。
            猜你喜欢
            • 2021-10-27
            • 1970-01-01
            • 2014-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-24
            • 1970-01-01
            • 2018-10-12
            相关资源
            最近更新 更多