【问题标题】:what is the meaning of this (redundant?) python expression?这个(冗余?)python表达式的含义是什么?
【发布时间】:2012-02-22 18:23:40
【问题描述】:
str='test'
example={'test':'value',}
return str in example and example[str] or None

为什么在example 中对密钥str 进行看似多余的额外测试?

【问题讨论】:

  • 用英语和最近的 Python 你会写return example[str] if str in example else None
  • @JochenRitzel - 这再次错过了我在回答中提出的观点。根据他的示例,它需要捕获真值测试为 False 的值
  • @jdi:大多数时候,当我看到or 用于返回两个值之一时,其意图并不是真正阻止返回 0、''、[] 等,这只是默认的“聪明”单行,因为人们担心如果他们必须输入整个if 块/表达式,他们的键盘会磨损。我个人认为这有点反模式。在这种情况下,我猜您无法区分存储在键下的“虚假”值与未存储的键的事实更有可能是未考虑的极端情况(即错误),而不是所需的行为。
  • 我不会以任何方式捍卫 OP 发布的实际代码。我只是想回应他对这段代码的询问。这不是他意图的问题,而是他要求扩展的确切 sn-p。在这个 sn-p 中,它确实过滤掉了 eval 为 False 的值。如果他的问题是“有没有更好的方法来实现这个 x 或 y 结果?”,那么就会有不同的答案流提供替代方案。

标签: python testing logic expression


【解决方案1】:

在这个具体的例子中,检查是首先确保'test'实际上是示例字典中的有效键,否则你会得到一个KeyError异常。然后逻辑继续检查密钥并返回它,或者如果 example[str] 的值 eval 为 False,则返回 None

如果这个例子简单的做会容易很多:

str='test'
example={'test':'value',}
return example.get(str, None) or None

更新

甚至更简单,因为不需要 get() 的额外参数:

return example.get(str) or None

更新 2:分解来自 OP 的真值测试和布尔运算(基于 cmets)

example = {
    'test' : 'value', 
    'test2': 0, 
    'test3': [],
}
test = lambda k: k in example and example[k] or None
print test('test')
# value
print test('test2')
# None
print test('test3')
# None

【讨论】:

  • 如果你只是这样做会更容易return example.get(str, None)
  • @julio.alegria - 这是不正确的。简单地返回将允许返回空字符串、int 0 或任何 null 类型。 OPs 示例表明,如果值评估为 False,它将返回 None。
  • 我建议您reading more 了解get() 方法。如果没有找到你传递的key,则返回None(不是False)或者默认值(第二个参数)。所以实际上,甚至更容易(结果相同)会做return example.get(str)
  • @julio.alegria - 你又错了。你可能应该自己阅读。如果值为 0,d.get('test') 将返回 0。如果您真的想进一步简化我的示例,您可以建议 d.get('test') or None
  • 用户在哪里说它不应该返回 0?
【解决方案2】:

对于初学者来说,在您查找不存在的密钥的情况下,行为是不同的(额外的测试将防止抛出 KeyError 异常)。

但是,它比这更进一步,因为example[str] 在布尔上下文中可能为假。例如,它可能是一个空字符串。

>>> str='test'
>>> example={'test':[],}
>>> str in example and example[str] or None
>>> str in example or None
True

所以它不是很多余。 str in example 检查密钥是否存在,而 and example[str] 也在检查值的真实性。

【讨论】:

  • 当然,如果这实际上是确切的代码,则问题更可能是复制/粘贴操作。
【解决方案3】:

由于 Python 懒惰地评估布尔值,您可以安全地在简单测试中省略括号。这可能会更容易阅读:

(str in example and example[str]) or None

简单的英语:

“确保字典 example 具有键 str 并且该键也具有非 False 值。如果是,则返回键 example[str] 的值。否则返回 None

【讨论】:

    【解决方案4】:

    优雅的失败。如果键不存在,则查找“example[str]”将在运行时失败。您将遇到错误,终止您的应用程序并获得回溯。通过首先检查密钥,您将返回 None 值,您的应用程序将继续其愉快的方式。

    另一种更通用的方法是捕获异常并因此返回 None。

    def testfun():
        str='test2'
        example={'test':'value',}
        try:
            return example[str]
        except KeyError:
            return None
    

    【讨论】:

    • 这不提供检查现有值是否评估为 None 的相同保护
    • 你是什么意思?在什么情况下输出会有所不同?
    • 如果 example['test'] == 0 那么它最终会返回 0 而不是 None。 OPs 示例还检查该值是否计算为 False。你的没有。
    【解决方案5】:

    如果密钥不存在,它将得到KeyError exception

    #!/usr/bin/python
    
    str='test'
    example={'test':'value',}
    
    if str in example and example[str]:
        print example[str]
    else:
        print False
    

    【讨论】:

      【解决方案6】:

      str in example 是一个布尔测试,用于查看 str 是否是 example 中的键,而 example[str] 产生与该键关联的实际值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多