【问题标题】:Multiple parameters for the __contains__ function__contains__ 函数的多个参数
【发布时间】:2011-04-25 08:20:44
【问题描述】:

是否可以在一个列表中传递多个参数的“__ contains __”函数?我想检查至少我在一个列表中的一项是否存在于另一个列表中。

例如: [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']

我想检查其中一项 (8,5,'f') 是否在该列表中。

我该怎么做?

【问题讨论】:

    标签: python contains


    【解决方案1】:

    AFAIK,__contains__ 只接受一个参数并且不能更改。

    但是,您可以执行以下操作以获得所需的结果:

    >>> a = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']
    >>> any(map(lambda x: x in a, (8,5,'f')))
    True
    

    >>> from functools import partial
    >>> from operator import contains
    >>> f = partial(contains, a)
    >>> any(map(f, (2,3)))
    False
    

    【讨论】:

    • +1 用于任何使用,也很好地展示了部分。使用生成器而不是 map+lambda 更符合 Python 风格。
    • 正如kevpie 指出的那样,第一个建议将比any(x in a for x in (8,5,'f')) 更清晰。每当将 lambda 作为第一个参数传递给 map 时,强烈暗示应该改用推导式或生成器表达式。
    【解决方案2】:

    使用内置 set 类型。

    >>> l =  [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']
    >>> s = (8,5,'f')
    >>> bool(set(s) & set(l))
    True
    

    Set 方法也将可迭代对象作为参数,避免创建集合。

    最简洁:

    2.6 提供了 set.isdisjoint(other),它可能经过优化,可以在找到公共元素后立即返回。

    >>> not set(l).isdisjoint(s)
    True
    

    如果你想循环播放:

    >>> any((val in s) for val in l)
    True
    

    【讨论】:

      【解决方案3】:

      你可以使用集合:

      list1 = [0,1,4,8,87,6,4,7,5,'a','f','er','fa','vz']
      tuple1 = (8,5,'f')
      
      def my_contains(first, second):
          return bool(set(first).intersection(second))
      
      my_contains(list1, tuple1) # True
      my_contains(list1, [1]) # True
      my_contains(list1, (125,178,999)) # False
      

      【讨论】:

      • +1,很好地使用了集合。 intersection() 可以直接采用第二个可迭代对象。你可以通过调用 bool(someset) 来产生 True/False。 return bool(set(first).intersection(second))
      • 需要注意的一个关键点是,基于集合的方法只有在所有涉及的值都是可散列的情况下才有效。如果不能保证,则有必要采用迭代解决方案(可能使用 any 内置)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多