【问题标题】:Set Intersection with None设置无交集
【发布时间】:2019-02-04 09:01:38
【问题描述】:

我在设置操作交点时遇到问题。

假设我有一个列表A = [0,1,2,3] 和一个整数B = 0。当我查看if B in A: 时,我当然会得到True

但是当AB默认等于None时,我不能做AB的交集运算。

我正在寻找一种方法来执行以下操作而不会出错:

A = None
B = None

if B in A:
    raise KeyError('B in A')

通常A 是一个python 列表,B 是一个字符串。但是我需要将它们默认设置为None,而它们是我函数中的参数;它们的值必须为None

PS:使用搜索算法获取TrueFalse。并不重要。我只需要得到TrueFalse,这样我就可以安排我的错误提升。

【问题讨论】:

  • 你试过A=[None]吗?
  • 你不能在函数的开头设置A = set() if not A else A吗?
  • 它们应该是默认的 None
  • 你为什么不能检查他们是否是None
  • 因为重点是检查 B 是否在 A 中,并且在我的函数参数中它们必须是 None 作为默认值。

标签: python set intersection nonetype operation


【解决方案1】:

最简单的方法是设置A = [] 而不是A = None(对于最终将成为列表的东西来说这是一个合理的值)。

如果A 是函数的参数,请注意不要写

def f(A=[])

但是,相反

def f(A=None):
    if A is None:
       A = []

【讨论】:

  • 这看起来不错,我也可以A.isdisjoint(B)吗?
  • @Icedkk 不,那是一套方法。你说A 是一个列表。如果你想要一个集合,为什么不使用一个集合对象。 A = set()?
  • 小心:OP 说他从参数中得到None。不要在参数中使用可变的默认值。
  • @FHTMitchell 你是对的,然后它会创建一个集合......无论如何类似于 isdisjoint() 到一个列表?
  • 但是为什么还要使用list,如果你要把它变成一个集合,从一开始就使用一个集合。 set(A).isdisjoint(...) 可以,但效率不高。
【解决方案2】:

为什么不尝试检查 A 或 B 本身是否为 None?

A = None
B = None

if None not in [A, B] and B in A:
    print('B in A')
else:
    print('B or A is None, or B is not in A')

【讨论】:

    【解决方案3】:

    你可以试试:

    if B in (A or []):
    

    所以如果ANone 它会针对空列表进行测试并产生False

    如果A 是一个空列表,它也会对or 的最右边的操作数进行测试,但结果是一样的。

    更大的范围:如果你的函数中有默认值None

    def foo(A=None,B=None):
    

    将它们保留为 None,并在函数代码中更改它们,使默认参数不可变 ("Least Astonishment" and the Mutable Default Argument)。

    if A is None:
       A = []
    

    【讨论】:

      【解决方案4】:

      继续使用None 作为默认参数,然后将a 设置为空集set,如果它是None(根据python 约定,我使用小写参数名称):

      def f(a=None, b=None):
         if a is None:
             a = set()
      
          if b in a:
              raise KeyError('b in a')
      
          if a.isdisjoint(other_set):
             ...
      

      【讨论】:

        【解决方案5】:
        A = [None, 1, 2]
        B = None
        
        if B in A: # where A should be a list, it should be iterable
            print('done')
        

        输出

        done
        

        【讨论】:

          【解决方案6】:

          在函数中处理None-initialized 参数的常用方法是在所述函数的开头将它们分配给合理的默认值。我使用类型注释只是为了显示可以传递哪种值:

          from typing import List, Optional
          
          def check_intersect(A: Optional[List[str]] = None, B: Optional[str] = None):
              if A is None:
                  A = []
              if B in A:  # this can't fail any more 
                  raise KeyError('B in A')
          

          in 关键字(当然,如果它不是 for 循环的一部分..)需要一个 python 对象作为其右侧参数,而 offers a __contains__() 函数,None 没有。

          【讨论】:

            猜你喜欢
            • 2010-12-18
            • 2012-04-12
            • 1970-01-01
            • 2014-09-05
            • 1970-01-01
            • 1970-01-01
            • 2020-03-31
            • 2012-03-05
            • 2013-12-09
            相关资源
            最近更新 更多