【问题标题】:Proper way to test for "x" or "y" in a string?测试字符串中“x”或“y”的正确方法?
【发布时间】:2019-02-10 22:23:03
【问题描述】:

所以我想在 Python (3.7) 中演示一个简单的 if 语句。 我最终编写了一个简单的代码(v1_alt.1)。

v1_alt.1 按预期工作,我觉得它很容易演示 if 语句是如何工作的。我也想评估前任。 '深绿色' 为 True。

但我觉得它应该写得有点不同。所以我最终测试了不同的代码。我最终用不同的方法来证明什么是有效的,什么是无效的。但我有问题理解它以及为什么。

### v1
color = input("v1 - What is my favourite color? ") # ex. dark green

# alt.1 - Working code. Accept ex. 'dark green'.
if "red" in color or "green" in color:
    print(f"You entered {color}. That is is one of my favourite colors! "
          "(v1_alt.1)")

# alt.2 - Not working code. Will always evaluate True (Why?)
if "red" or "green" in color:
    print(f"You entered {color}. That is is one of my favourite colors! "
          "(v1_alt.2)")

# alt.3 - Not working code. Will always evaluate Red True, but not Green (Why?)
if ("red" or "green") in color:
    print(f"You entered {color}. That is is one of my favourite colors! "
          "(v1_alt.3)")

# alt.4 - Not working code. Will always evaluate True (Why)
if ("red" or "green" in color):
    print(f"You entered {color}. That is is one of my favourite colors! "
          "(v1_alt.4)")

# alt. 5 - Working code, but I want to accept ex. 'dark green'
if color in {"red", "green"}:
    print(f"You entered {color}. That is is one of my favourite colors! "
          "(v1_alt.5)")


### v2
fav_colors = ("red", "green")
color = input("v2 - What is my favourite color? ") # ex: dark green

for c in fav_colors:
    if c in color:
        print(f"You entered {color}. That is correct! "
          f"{c} is one of my favourite colors "
          "(v2_alt.1)")

if [c for c in fav_colors if c in color]:
    print(f"You entered {color}. That is correct! "
          f"{c} is one of my favourite colors "
          "(v2_alt.2)")

为什么 v1_alt.2 和 v1_alt.4 总是评估为 True?

为什么在 v1_alt.3 中,“红色”答案而不是“绿色”答案评估为 True?

编写 v1_alt.1 的最佳方式是什么?我可以编写一个 v2 代码,但我想保持简单以用于教程目的。

【问题讨论】:

  • 我愿意any(option in colour for option in ("red", "green")

标签: python python-3.x


【解决方案1】:

在 Python 中,如果 bool(x) is True,则对象 x 被称为真,即该对象在布尔上下文中等效于 True

# alt.2 - Not working code. Will always evaluate True (Why?)
if "red" or "green" in color:

该表达式被评估为"red" or ("green" in color)。因为"red" 是真的,所以表达式也是(甚至没有评估第二部分)。

# alt.3 - Not working code. Will always evaluate Red True, but not Green (Why?)
if ("red" or "green") in color:

括号中的表达式计算结果为 "red",因为在 Python 中 orand 返回它们的参数。 or 返回第一个参数,如果它是真实的,或者返回第二个参数在任何其他情况下。所以,整个语句可以简化为if 'red' in color: ...

您的第四个示例与第二个示例等效:这些括号不会改变任何内容。

# alt. 5 - Working code, but I want to accept ex. 'dark green'
if color in {"red", "green"}

那么没有什么能阻止您将颜色添加到该集合:{"red", "green", "dark green"}

编写 v1_alt.1 的最佳方式是什么

几乎没有任何“最佳方法”,因为这些东西往往是口味问题。话虽这么说,如果你有一组固定的颜色,我会使用一个元组或一个集合,就像你的“alt 5”例子一样。如果您有一组固定的基色,并且修饰符总是位于开头(如“深绿色”)并以空格分隔,则可以拆分传入的字符串:if color.split()[-1] in base_colors,其中base_colors 是一组/tuple/list/(任何可搜索的数据结构)基本颜色。如果您的任务需要复杂的逻辑,那么使用专用函数会更好:

def validate_color(base_colors, color):
    """
    Validate a color.
    """
    return color.split()[-1] in base_colors


if validate_color(base_colors, color):
    ...

函数封装了实现细节,否则这些细节会“污染”您的主执行图。此外,它可以安全地修改,而无需接触其他部分(只要你保持纯净)。

【讨论】:

  • 这是一个很好的答案。我要狡辩的一件事是,在散文的第一段中,您说“"red" is always True" (and something similar later on that's similar when discussing and` 和or)。这不是真的正确,因为您可以看到评估"red" == True。更准确的说法是"red" 是“真实的”(意味着bool("red") == True)。在布尔上下文中使用术语“真实”和“虚假”来描述非bool 对象很有用,不会混淆它们使用 Python 的实际 bool 对象 TrueFalse
  • @Blckknght 或者只是说“bool("red") 总是正确的”;-)
  • 谢谢。我可以清楚地看到 alt 的问题。 2->替代。 4 现在当你解释它。然后我知道我会坚持使用alt。 1 暂时。我很好奇是否有更简单的方法来做到这一点(例如 Python2 与 Python3 语法)——该示例旨在向孩子们解释 if/else/or/and。随着我们的前进,我们将通过其他方式取得进展。
  • @Blckknght 是的,这是一个很好的修正;我自己对这些问题犹豫不决,因为 Python 文档倾向于使用“true”和“false”,而没有明确区分 TrueFalse
  • @Mr.Anderson 正如我已经提到的,更传统的做法是您的alt. 5 示例或专用函数。 Py2 和 Py3 在这方面是相似的。如果您以儿童为目标,您可以使用一组固定的颜色,而无需引入额外的逻辑来处理复合颜色。或者您实际上可以解释什么是函数/方法调用。选择很大程度上取决于您的最终目标和受众。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
  • 2017-06-06
  • 2015-12-10
  • 2011-12-27
  • 2014-04-27
  • 1970-01-01
相关资源
最近更新 更多