Python';s相当于Java';s Set.add()?
Java的Python';s相当于Java';s Set.add()?,java,python,set,Java,Python,Set,Java的Set.add函数将返回一个布尔值,如果该集合尚未包含指定的元素,则该值为true Python的Set.add没有返回值 在Python中,如果我想做同样的事情,我必须先检查它是否在集合中,如果不在集合中,就添加它 有没有更简单的方法(最好是一个班轮) 参考: 不,Python的set实现没有这样的方法;正如您所指出的,您必须单独测试是否存在: if obj not in setobj: setobj.add(obj) 或者,我通常做的: if obj in setobj:
Set.add
函数将返回一个布尔值,如果该集合尚未包含指定的元素,则该值为true
Python的Set.add
没有返回值
在Python中,如果我想做同样的事情,我必须先检查它是否在集合中,如果不在集合中,就添加它
有没有更简单的方法(最好是一个班轮)
参考:不,Python的set实现没有这样的方法;正如您所指出的,您必须单独测试是否存在:
if obj not in setobj:
setobj.add(obj)
或者,我通常做的:
if obj in setobj:
return # or break out of a loop, etc.
# handle the case where the set doesn't have the object yet.
您始终可以对集合
类型进行子类化:
class SetWithPresenceCheck(set):
def add(self, value):
not_present = value not in self
super(SetWithPresenceCheck, self).add(value)
return not_present
请注意,
Set.add()
返回布尔值的真正原因是添加和测试原子操作;接口的实现可以(可选地)使方法同步,并让调用方避免竞争条件。Python的内置集并没有做出任何线程安全承诺。无论如何,union操作符比add操作符快得多
>>> set_a = set('pqrs')
>>> set_b = ['t', 'u', 'v']
>>> set_a |= set(set_b)
>>> set_a
set(['p','q','r','s','t','u','v'])
可能使用三元条件运算符:
the_set.add(what_ever) or True if what_ever not in the_set else False
如果
集合中有什么,则返回False;如果不在则返回True。如果需要一行,则可以使用或添加元素,前提是该元素不在集合中(短路评估),和not
来反转返回值,同时强制执行bool
,将add
返回的None
转换为True
,否则只需在检查中反转的结果:
>>> s = set()
>>> not(42 in s or s.add(42))
True
>>> not(42 in s or s.add(42))
False
>>> s
set([42])
但是,由于这一行代码可能不太容易掌握,并且您必须编写要插入两次的值,因此您可能应该将其作为一个函数,然后它使用多少行并不重要
def in_or_add(s, x):
return not(x in s or s.add(x))
在python中,如果您添加了集合中已有的内容,则不会添加重复内容。@pwnsauce:在Java中也不会。但是Set.add()
方法会告诉您元素是否已经存在,这可以稍微简化代码。当然,Java需要它在代码简单性方面所能得到的所有帮助。在添加元素之前,联合不会告诉你元素是否存在。如果你只想添加一个元素,为什么还要创建一个完整的集合呢?@MartijnPieters:tue,但OP想将元素添加到集合中。工会将为他服务。不,OP希望在一个步骤中添加时告知元素是否已经存在。哦,是的。我应该更仔细地阅读这个问题。谢谢你指出我的错误。这是无效的语法。赋值(bool\u ready\u in=True
)是一个语句,不是表达式,不能嵌套在另一个表达式中。因此,现在需要在单独的语句中测试None
或False
。这并不比单独的包含检查更有用。@MartijnPieters是的,但您必须在java:set.add()中执行相同的操作。
no?set.add()如果该值不在集合中,则添加该值并返回True或False,对吗?就像这样另外,你真的认为像这样的扩展条件表达式更可读更清晰吗?确切地说,Set.add()
返回一个布尔值。返回False
(布尔值)或None
(False-y值)。如果在条件下不能使用此选项,则需要先添加为None
或类似选项。Python方法的问题是,在输入值中几乎没有(如果有)重复项的情况下,它会强制对要添加的每个元素进行双重查找。当然,这通常不是一个非常昂贵的查找,但是能够将其提升到实际实现中,从而完成单个查找将是一个很好的效率提升。@DonalFellows:在绝大多数情况下,这一成本可以忽略不计,但是如果您担心的话,基准测试表明,它实际上会对您的用例产生影响,然后您可以使用oldlen=len(self)
,super().add(value)
,return len(self)>oldlen
作为子类中的add
实现。设置的长度是每次元素数更改时更新的缓存值的O(1)查找。我认为这不会有什么区别,除非元素的\uuuuuuuuuuuuuuuuuuuuuuuu散列
实现成本高昂且无法缓存,或者\uuuuuuueq
实现成本高昂。@DonalFellows:同样,Java(和其他语言,如Rust)返回bool的主要原因(或更新映射中的键值对时存储的旧值)是为了支持并发性,而不是性能。Python不是一种为速度而构建的语言,在任何情况下,它都是一种为可读性、可维护性和开发速度而构建的语言。当集合中的双重查找开始起作用时,无论如何,您可能想将关键部分转移到编译语言扩展中。