【问题标题】:Check if list is either empty or only containing zeroes检查列表是否为空或仅包含零
【发布时间】:2016-03-05 18:05:03
【问题描述】:

现在,在我的代码中,我有两个列表:aboveAdj1aboveAdj2,它们要么包含 1 和 0,要么为空:

if len(aboveAdj1) and len(aboveAdj2):
    perAboveFix = 100*int(sum(aboveAdj1) + sum(aboveAdj2))/int(len(aboveAdj1) + len(aboveAdj2))

如果aboveAdj1aboveAdj2 都不为空或全为零,那么我想计算比率。如果另一个变量为空,是否有一种有效/简短的方法可以仅基于一个变量计算比率,而无需编写一堆if 语句?

例如,如果aboveAdj1 为空或全为零,则计算:

perAboveFix = 100*int(sum(aboveAdj2))/int(len(aboveAdj2))

反之亦然。

【问题讨论】:

  • 这行得通吗? if len(aboveAdj1) and len(aboveAdj2) and sum(aboveAdj1) and sum(aboveAdj2):我不完全理解你的问题
  • “aboveAdj1 为零”是什么意思?你的意思是所有的值都是零?
  • 如果您要测试的唯一选项是 aboveAdj1 为空或 aboveAdj1 用零填充,您可以使用 if sum(aboveAdj1): do_stuff。一个空列表或一个用零填充的列表的总和是 0 是 Falsey。
  • 对不起,我的意思是它是空的还是全零
  • any(aboveAdj1)sum 快一点点。

标签: python arrays performance list if-statement


【解决方案1】:

基本上你想检查是否:

  • 列表不为空
  • 并且它们至少包含一个不为零的值。

any() 函数只是为您执行此操作,因为如果列表不为空且至少包含一个非零值,any(some_list) 就是 True

因此,如果您只想在两个列表都有效时计算比率,您可以这样做:

if any(aboveAdj1) and any(aboveAdj2):
    perAboveFix = 100 * (sum(aboveAdj1) + sum(aboveAdj2)) / (len(aboveAdj1) + len(aboveAdj2))

否则,如果你想在至少一个列表有效时计算它,那么你可以这样做:

if any(aboveAdj1 + aboveAdj2):
    perAboveFix = 100 * (sum(aboveAdj1) + sum(aboveAdj2)) / (len(aboveAdj1) + len(aboveAdj2))

还请注意,您不需要使用int() 函数,因为正如您所说,您的列表仅包含0s 和1s,以及len()已经返回整数值。

【讨论】:

    【解决方案2】:

    如果您要测试的唯一选项是 aboveAdj1 为空或 aboveAdj1 用零填充,您可以这样做

    if sum(aboveAdj1):
        # some non-zero element exists
        do_stuff_as_normal
    else:
        do_stuff_differently
    

    空列表或用零填充的列表的总和是0,即 Falsey。

    或者,如果您只是害怕除零,您可以跳过所有条件并简单地尝试一下,但您可能会被零除的情况除外。这是 Python 中的常见习语。

    try:
        your_normal_division
    except ZeroDivisonError:
        alternate_formula
    

    【讨论】:

    • Try-except 在我看来是最pythonic的
    • 在所有元素都为零的情况下,总和可能为零。
    • any() 更适合这个问题,因为它不需要遍历整个列表
    • @SvenMarnach 这通常是正确的,但 OP 明确表示列表不包含负值,因此在这种情况下可以安全地假设只有当列表的总和为零为空或用零填充。
    【解决方案3】:

    好吧,空列表和零列表的sum 将返回0,这意味着如果aboveAdj1 == ([] or [0,0,0] 那么sum(aboveAdj1) + sum(aboveAdj2) == sum(aboveAdj2)。这意味着您唯一需要担心的是零列表的len(即[0,0,0] 应该返回len == 0)。你可以用三元表达式来处理这个:

    perAboveFix = 100*int(sum(aboveAdj1) + sum(aboveAdj2))/  #just a break for readability
    int((len(aboveAdj1) if sum(aboveAdj1) else 0) + 
    (len(aboveAdj2) if sum(aboveAdj2) else 0))
                       ^   ^ checks that sum is not 0
    

    然后,您只需检查至少一个列表的长度是否有效,因为除以 0 是一个数学错误。通过使用内置的any 函数,您可以同时检查长度和总和:

    if any(aboveAdj1) or any(aboveAdj2):
         #expression here
    

    因为any 将在所有元素为 0 或为空时返回 false。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 2010-11-19
      • 2019-11-02
      • 2011-01-25
      • 2011-08-17
      • 2012-08-26
      • 1970-01-01
      相关资源
      最近更新 更多