【问题标题】:does adding element to a set return true if it is successful in python?如果在python中成功,将元素添加到集合中是否返回true?
【发布时间】:2014-01-20 09:15:54
【问题描述】:

据我了解,向set 添加元素不会返回任何内容。 例如:

>>> s=set([1,2,3])
>>> s.add(1)
>>> b = s.add(1)
>>> b
>>> b = s.add(5)
>>> b
>>> print b
None
>>> b = s.add(5)
>>> print b
None

但我很困惑remove duplicates of a list while preserving order 的这个函数是如何工作的:

def f7(seq):
    seen = set()
    seen_add = seen.add
    return [ x for x in seq if x not in seen and not seen_add(x)]

not seen_add(x) 无论我是否添加重复项,都始终返回 true。 唯一真正的检查是如果x not in seen,因为如果失败,它将不会执行not see_add(x)

这是我的理解还是我遗漏了什么?

但是,在这里,not seen_add(1) 如果我添加重复元素或唯一元素,则返回 true。 这很令人费解,所以这里的not 只是做空检查吗?但是seen_add() 没有返回一个集合来进行empty 检查。以及为什么seen_add(2) 不返回任何东西,但not seen_add(1) 返回boolean True

>>> seen=set()
>>> seen_add=seen.add
>>> seen_add(1)
>>> seen
set([1])
>>> seen.add(2)
>>> seen
set([1, 2])
>>> not seen_add(1)
True
>>> not seen_add(4)
True

【问题讨论】:

    标签: python list function set add


    【解决方案1】:

    如您所见,seen_add(x) 总是返回 None

    现在,not NoneTrue

    >>> not None
    True
    

    这在documentation中有解释:

    5.1。真值测试

    可以测试任何对象的真值,用于ifwhile 条件或作为以下布尔运算的操作数。以下值被认为是错误的:

    • None
    • False
    • ...

    由于not seen_add(x) 始终为True,它对if 的结果没有影响。仅用于将x 添加到seen 的副作用。

    换一种说法,如下:

    seen_add = seen.add
    return [ x for x in seq if x not in seen and not seen_add(x)]
    

    是一种更短(并且可能更高效)的编写方式:

    result = []
    for x in seq:
      if x not in seen:
        result.append(x)
        seen.add(x)
    return result
    

    【讨论】:

    • 虽然这可行,但这是正确的方法。因为not seen_add(x) 总是True,那为什么还要在if 上查看呢
    • @eagertoLearn:因为您不能将语句放入列表推导式中,只能放入表达式。
    • 也许你应该解释一下布尔测试的快捷方式。
    • @StevenRumbalski:我本来打算去的,但后来决定在这里不相关(因为如果x 已经在seen 中,则调用seen_add(x) 是无操作的)。我有一种感觉,试图解释短路会使水域更加混乱......
    • @NPE:谢谢,我知道short-circuiting。我只是对为什么总是返回True 的东西是if 的一部分感到困惑。但这仅仅是因为list comprehension takes expressions 正如您所指出的。并指出 not NoneTrue 在 Java 中不一样,我熟悉
    【解决方案2】:

    正如其他人所说,not seen_add(x) 的计算结果始终为True,因此它仅用作将加法语句添加到列表理解中的技巧。由于x and True 的逻辑值等于x,这不会改变if 的行为。

    由于andshort-circuit 行为,这样做的另一件事是,仅当左侧参数为True 时,and 的右侧参数才会执行。所以对seen.add() 的调用仅在元素尚未在集合中时才进行。

    等效的python代码是:

    def f7(seq):
        seen = set()
        result = []
        for x in seq:
            if x not in seen:
                result.append(x)
                seen.add(x)
        return result
    

    使用列表理解的解决方案可能更快,但对我来说太神秘了。

    【讨论】:

      【解决方案3】:

      这是因为not NoneTrue

      【讨论】:

        【解决方案4】:

        也许这对你有帮助

        def add_ok(set, value):
            return len(set) != (set.add(value), len(set))[1]
        
        
        print(add_ok(a, 1))
        print(add_ok(a, 1))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-22
          • 2019-05-27
          • 2022-12-18
          • 1970-01-01
          • 2018-09-24
          • 1970-01-01
          • 2019-05-15
          • 2020-06-17
          相关资源
          最近更新 更多