【问题标题】:if else in a list comprehension [duplicate]if else 在列表理解中[重复]
【发布时间】:2011-05-23 07:49:52
【问题描述】:

我有一个列表l

l = [22, 13, 45, 50, 98, 69, 43, 44, 1]

对于45以上的数字,我想加1;对于小于它的数字,5。

我试过了

[x+1 for x in l if x >= 45 else x+5]

但它给了我一个语法错误。我怎样才能在列表理解中实现这样的ifelse

【问题讨论】:

    标签: python list list-comprehension if-statement


    【解决方案1】:

    就像在[a if condition1 else b for i in list1 if condition2] 中一样,两个ifs 与condition1condition2 做两种不同的事情。 (a if condition1 else b) 部分来自 lambda 表达式:

    lambda x: a if condition1 else b
    

    而另一个 condition2 是另一个 lambda:

    lambda x: condition2
    

    整个列表理解可以看作是mapfilter的组合:

    map(lambda x: a if condition1 else b, filter(lambda x: condition2, list1))
    

    【讨论】:

    • 这是一个很棒的见解
    • 对于两个条件 sn-ps 到 mapfilter 的映射非常好。
    【解决方案2】:
    [x+1 if x >= 45 else x+5 for x in l]
    

    作为奖励,这里是评论,我写信是为了记住我第一次犯这个错误:

    Python的条件表达式是a if C else b,不能用作:

    [a for i in items if C else b]
    

    正确的形式是:

    [a if C else b for i in items]
    

    即使有一个有效的形式:

    [a for i in items if C]
    

    但这与您通过C 过滤的方式不同,但它们可以组合:

    [a if tC else b for i in items if fC]
    

    【讨论】:

    • @Dan D. 多个ifs 怎么样?即[x+1 if x >= 45 x-1 if x<10 else x+5 for x in l]?我有一个与 if 语句类似的problem
    • @3kstc:为此:[x+1 if x >= 45 else (x-1 if x < 10 else x+5) for x in l]。我会看看你的问题。
    • @Dan D. 谢谢正确的形式是:[a if C else b for i in items] 这对我有用。
    • 不是 OP,但感谢您的回答。对于你的最后一行代码,你能给我解释一下for i in items if fC 做了什么吗?这是否意味着您仅对items 中的元素使用a if tC else b 条件可以使fC 为真?谢谢。
    • @BowenLiu 是的。重点是显示三元组A if C else B 中的ifi for i in items if p(i) 中的条件if 之间的区别。如果您命名结果,则每个理解都可以写成语句。 v = [A if q(i) else B for i in L if p(i)] 变为 v = []for i in L: if p(i): v.append(A if q(i) else B)
    【解决方案3】:
    >>> l = [22, 13, 45, 50, 98, 69, 43, 44, 1]
    >>> [x+1 if x >= 45 else x+5 for x in l]
    [27, 18, 46, 51, 99, 70, 48, 49, 6]
    

    如果<condition> 做某事,否则做其他事情。

    【讨论】:

    • 可能应该使用与x 不同的变量作为底部解释中的条件,因为在示例中使用x 而不是条件。
    • 如果满足条件,只在列表中包含变量呢? else 会通过吗?
    • 似乎条件也可以放在最后,例如提取具有特定条件的对象(本例中的名称)var_list = [v for v in tf.all_variables() if v.name == 'C:0']
    • 我发现如果将条件放在开头,那么它需要 if 和 else(它必须产生一个元素) - 但把它放在最后,只需要 if(你不能放一个 else 那里)。
    • @Jeppe 正确,这是一个重要的区别。如果您只想保留某些元素(即:您不一定希望每次迭代都有一个数组条目),那么您需要将条件放在末尾。
    【解决方案4】:

    我刚刚遇到了类似的问题,发现这个问题和答案非常有用。这是我感到困惑的部分。我明确地写它是因为没有人真正用英语简单地说明它:

    迭代结束。

    通常,循环会进行

    for this many times:
        if conditional: 
            do this thing
        else:
            do something else  
    

    每个人都像第一个答案一样简单地陈述列表理解部分,

    [ expression for item in list if conditional ] 
    

    但这实际上不是你在这种情况下所做的。 (我试图这样做)

    在这种情况下,它更像是这样的:

    [ expression if conditional else other thing for this many times ] 
    

    【讨论】:

      【解决方案5】:

      您还可以将条件表达式放在列表推导内的括号中:

          l = [22, 13, 45, 50, 98, 69, 43, 44, 1]
          print [[x+5,x+1][x >= 45] for x in l]
      

      [false,true][条件]是语法

      【讨论】:

        【解决方案6】:

        您收到此错误的原因与列表理解的执行方式有关。

        请记住以下几点:

        [ expression for item in list if conditional ]
        

        相当于:

        for item in list:
            if conditional:
                expression
        

        expression 的格式略有不同(想想在句子中切换主语和动词顺序)。

        因此,您的代码 [x+1 for x in l if x >= 45] 会这样做:

        for x in l:
            if x >= 45:
                x+1
        

        但是,此代码 [x+1 if x >= 45 else x+5 for x in l] 执行此操作(在重新排列 expression 之后):

        for x in l:
            if x>=45: x+1
            else: x+5
        

        【讨论】:

        • 我的代码 user_albums = [{'albums': links['link']} for links in _details['albums']['data'] if 'link' in links.keys () else pass] 在 else 条件下传递错误
        • @shihon 在列表理解中不需要else pass;当满足条件if 'link' in links.keys() 时,这暗示您不希望列表中包含{'albums': links['link']} 项目。正确格式:user_albums = [{'albums': links['link']} for links in _details['albums']['data'] if 'link' in links.keys()]
        • 这意味着,如果数据不存在或为空,它会自己处理这个异常??
        • @shihon 当'link' in links.keys()False 时,Python 列表推导会跳过表达式以将{'albums': links['link']} 添加到列表中。您扩展的代码的行为方式与我上面的答案中的[x+1 for x in l if x >= 45] 相同。
        【解决方案7】:

        您可以将条件移至:

        v = [22, 13, 45, 50, 98, 69, 43, 44, 1]
        [ (x+1 if x >=45 else x+5)  for x in v ]
        

        但它开始看起来有点难看,所以使用普通循环可能会更好。请注意,我使用v 而不是l 作为列表变量,以减少与数字1 的混淆(我认为在任何情况下都应避免将lO 作为变量名,即使在快速而肮脏的情况下也是如此示例代码)。

        【讨论】:

          【解决方案8】:

          您必须将表达式放在列表推导的开头,末尾的 if 语句过滤元素!

          [x+1 if x >= 45 else x+5 for x in l]
          

          【讨论】:

          • +1 用于明确区分条件句在理解开头和结尾的作用。您也可以同时进行这两项操作;例如['upper' if item.isupper() else 'lower' for item in 'Omg! paNCAkEs!!!' if item.isalpha()]
          • 太棒了!谢谢,有没有使用 else if 的选项
          • @vinSan 如果您想在列表推导中使用 elif,您可能已经超过了列表推导的预期复杂程度。将你的逻辑放在一个函数中,然后从你的列表理解中调用它。
          猜你喜欢
          • 1970-01-01
          • 2015-10-28
          • 2018-04-27
          • 2023-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多