【问题标题】:If vs. Elif in Python, which is better?Python 中的 if 与 Elif,哪个更好?
【发布时间】:2020-05-12 18:08:02
【问题描述】:

我正在阅读 Grokking Algorithms,这似乎是一本强烈推荐的书。我正在研究“二分搜索”的第一个算法,这个人使用两个“ifs”而不是“if”和“elif”。使用两个“ifs”会更好还是更快?

def binary_search(list, item):
    low = 0
    high = len(list) - 1

    while low <= high:
        mid = (low + high)
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
        else:
            low = mid + 1
    return None

my_list = [1,3,5,7,9]

【问题讨论】:

  • 逻辑不同(或者如果那里没有return 就会不同)。当if 为真时,elif 保证不会运行。给定回报,它们是等价的。
  • 顺便说一句,请参阅Why not upload images of code on SO when asking a question? -- 使用 cmets 注释的文本可被搜索引擎索引,具有辅助技术的人更容易访问,想要自己尝试代码的人可以复制/粘贴等。
  • 我猜 mid 分配不正确,应该是 mid = (low + high)/2 或 mid = low + (high-low)/2。

标签: python python-3.x if-statement


【解决方案1】:

示例1

>>> def foo():
    a = 10
    if a == 10:
        print("condition1")
    elif a == 10:
        print("condition2")
    else:
        print(0)    
>>> foo()
condition1
>>> 

当 if 为真时,elif 保证不会运行。

示例2

def foo():
    a = 10
    if a == 10:
        print("condition1")
    if a == 10:
        print("condition2")
    else:
        print(0)
>>> foo()
condition1
condition2
>>> 

例子3 修改example2的if语句。

if a == 10:
    print("condition1")
    return a

输出

>>> foo()
condition1
10

因此,在您的情况下,在第一个 if 语句中添加 return 具有类似于 if-elif 块的操作。 (return a) 阻止在 example3 中执行第二个 if 语句。

【讨论】:

    【解决方案2】:

    您使用多个ifs,当所有ifs 可能同时为真并且您希望执行其中的语句时。而当您知道只有单个块中的语句将被执行时,您使用ifelifselse。让我们看一些例子来说明清楚。

    这里,检查所有 if 语句的条件,最后一个 满足三个条件,因此其中的语句得到 执行。

    x = 105
    if (x%2):
        print("Multiple of 2")
    if (x%3):
        print("Multiple of 3")
    if (x%5):
        print("Multiple of 5")
    if (x%7):
        print("Multiple of 7")
    

    而在这种情况下,只检查条件直到 True 找到条件,一旦找到 True 条件,所有剩余的 条件语句被跳过。所以,这里只有里面的语句 第二个条件语句被执行。 (但是,请注意,即使只有 执行一个条件语句中的语句,有 是两张支票)

    if (x%2):
        print("Multiple of 2")
    elif (x%3):
        print("Multiple of 3")
    elif (x%5):
        print("Multiple of 5")
    else:
        print("Multiple of 7")
    

    因此,基本上这两个语句都有不同的用例,尽管如果您确定只有多个条件语句中的一个会被执行,使用ifelifselse 会更好。但是在这里,由于您有一个带有 if 循环的 return 语句,因此实际上情况有所不同。

    【讨论】:

      【解决方案3】:

      正如提到的其他答案,elif 在执行returnif 之后是不必要的。但他们没有涵盖性能影响。我认为测试会很有趣。

      事实证明,使用 if/elif/else 而不是单独的 if 可能会快一点。

      from timeit import timeit
      import random
      
      
      def count_items_ifelifelse(items, threshold):
          below, on, above = 0, 0, 0
          for item in items:
              if item > threshold:
                  above += 1
              elif item < threshold:
                  below += 1
              else:
                  on += 1
          return below, on, above
      
      
      def count_items_ififif(items, threshold):
          below, on, above = 0, 0, 0
          for item in items:
              if item > threshold:
                  above += 1
              if item < threshold:
                  below += 1
              if item == threshold:
                  on += 1
          return below, on, above
      
      
      def generate_items_and_threshold(count=100_000):
          """List of reproducible random numbers to test with. Set threshold at half"""
          items = list(range(count))
          random.Random(123).shuffle(items)
          threshold = count // 2
          return items, threshold
      
      
      def run_test():
          t1 = timeit(
              "count_items_ifelifelse(i, t)",
              setup="from __main__ import count_items_ifelifelse, generate_items_and_threshold; i, t = generate_items_and_threshold()",
              number=1000,
          )
          print("count_items_ifelifelse: {:.2f}".format(t1))
          t2 = timeit(
              "count_items_ififif(i, t)",
              setup="from __main__ import count_items_ififif, generate_items_and_threshold; i, t = generate_items_and_threshold()",
              number=1000,
          )
          print("count_items_ififif: {:.2f}".format(t2))
      
      
      if __name__ == "__main__":
          run_test()
      

      这个输出(Python 3.8.2,Windows):

      count_items_ifelifelse: 6.69
      count_items_ififif: 8.71
      

      大约快 20%,因为每个循环都需要更多不必要的 if 评估。另一方面,对于if/elif/else,性能会因数据的排序方式以及是否首先检查最常出现的条件而异。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-07-18
        • 1970-01-01
        • 1970-01-01
        • 2014-11-19
        • 1970-01-01
        • 2012-06-02
        • 2022-11-23
        • 1970-01-01
        相关资源
        最近更新 更多