【问题标题】:Python list comprehension - simplePython 列表理解 - 简单
【发布时间】:2011-10-01 11:13:53
【问题描述】:

我有一个列表,我想仅在满足特定条件的那些条目上使用特定函数 - 不修改其他条目。

示例:假设我只想将那些偶数的元素乘以 2。

a_list = [1, 2, 3, 4, 5]

想要的结果:

a_list => [1, 4, 3, 8, 5]

但是[elem * 2 for elem in a_list if elem %2 == 0] 产生[4, 8](它还充当了过滤器)。

正确的做法是什么?

【问题讨论】:

    标签: python list-comprehension


    【解决方案1】:

    使用conditional expression

    [x * 2 if x % 2 == 0 else x
     for x in a_list]
    

    (数学极客注:你也可以用

    解决这个特殊情况
    [x * (2 - x % 2) for x in a_list]
    

    但我还是更喜欢第一个选项;)

    【讨论】:

    • 谢谢,效果很好。另外,感谢您的编辑,接下来我会尝试使用相同的格式。
    【解决方案2】:
    a_list = [1, 2, 3, 4, 5]
    
    print [elem*2 if elem%2==0 else elem  for elem in a_list ]  
    

    或者,如果您有一个很长的列表要修改:

    a_list = [1, 2, 3, 4, 5]
    
    for i,elem in enumerate(a_list):
        if elem%2==0:
            a_list[i] = elem*2
    

    所以,只有偶数元素被修改

    【讨论】:

    • 不应该a_list[:] = list_comprehension 也可以就地替换吗?并且无需在 python 中循环?
    • @agf 所以它会在其他地方创建新列表,然后更新元素?太糟糕了,我认为由于列表推导的限制,我们可以保证一个元素只能在它被覆盖之前被引用,以便可以优化。
    • @Voo 就地赋值适用于任何可迭代对象,因此您可以改为从生成器表达式中进行。我刚刚尝试过,即使您使用reversed(a_list) 或生成的项目少于列表长度的生成器,这似乎也有效。不是我以前想过要做的事情;感谢您提出这个想法:)。
    • @agf 是的,我知道,但我认为我们可以像列表推导这样的特殊情况 - 较短的列表没有问题,因为我们只需要在之后设置大小变量,但我认为它是不够重要(谁知道失败)。但是,如果它与生成器一起使用,那对于大多数情况来说已经足够了 - 感谢您的测试和分享结果:)
    【解决方案3】:

    你可以使用 lambda:

    >>> a_list = [1, 2, 3, 4, 5]
    >>> f = lambda x: x%2 and x or x*2
    >>> a_list = [f(i) for i in a_list]
    >>> a_list
    [1, 4, 3, 8, 5]
    

    编辑 - 考虑到agf 的评论,我制作了我的代码的第二个版本:

    >>> a_list = [1, 2, 3, 4, 5]
    >>> f = lambda x: x if x%2 else x*2
    >>> a_list = [f(i) for i in a_list]
    >>> a_list
    [1, 4, 3, 8, 5]
    

    【讨论】:

    • 不要使用condition and true_value or false_value模拟三元运算; Python中有一个真正的版本。此外,无论哪种方式都不需要将它包装在 lambda 中,因为它是一个表达式而不是一个语句,它在列表理解中可以正常工作。 lambdas 有同样的限制,所以从不在列表解析或生成器表达式中需要一个。
    • @agf - 我理解(并同意)您对 lambda 的评论,但在这种情况下,在我看来,另一种方式(尽管远非绝对完美)将逻辑置于不同的层次从列表理解中选择项目。并感谢您提供有关 Python 三元运算符的其余部分。我制作了第二个版本来反映这一点。
    • lambda x:f() 是 12 个字符,[ for i in a_list] 是 18 - 所以你可以通过将表达式内联而不是 lambda 仅六个如果您有一个完整的单独列表理解而不是一个新函数,则可以使用更多字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多