使用集合时的常见模式如下:
number_list = [1,5,7,2,4,4,1,3,8,5]
number_set = set()
for number in number_list:
#we only want to process the number if we haven't already processed it
if(number not in number_set):
number_set.add(number)
#do processing of 'number' here now that we know it's not a duplicate
行if(number not in number_set):
和number_set.add(number)
让我感到烦恼,因为我们在这里进行了两次哈希查找,而实际上我们只需要一次哈希查找。
字典具有“setdefault”操作,它解决了一个非常类似的问题:“如果字符存在于字典中,则返回值,否则插入此默认值然后返回默认值”。如果你天真地这样做,IE以下,你执行两次哈希查找,但setdefault允许你在一个
中执行if item_key in dict:
dict[item_key].append(item_value)
else:
dict[item_key] = [item_value]
套装是否有相同的操作?像if(number_set.check_if_contains_and_then_add(number)):
这样的东西,但名字更好。
答案 0 :(得分:2)
没有。
setdefault
方法用于设置字典中键的默认值,集合没有值,因此完全没有意义。
如果订单无关紧要,请尝试此操作。
number_list = [1,5,7,2,4,4,1,3,8,5]
number_set = set(number_list)
for number in number_set:
#do processing of 'number' here now that we know it's not a duplicate
答案 1 :(得分:2)
如果探查器告诉您哈希查找会产生重要的运行时间,那么这可能会解决它。
def add_value(container, value):
oldlen = len(container)
container.add(value)
return len(container) != oldlen
if add_value(number_set, number):
# process number
但为什么会这样呢?也许是由于慢__hash__
方法,虽然我现在可以告诉你(a)散列整数不慢,(b)如果可能的话,最好用慢{{1}制作类。缓存结果而不是减少调用次数。或者可能是由于__hash__
慢,这很难处理。最后,如果内部查找机制本身很慢,那么你可以做很多事情来加速你的程序,因为运行时一直在进行哈希查找,在范围内查找名称。
__eq__
返回一个表示该集合是否发生变化的值可能会很好,但我认为这个想法违背了Python库的原则(诚然不被普遍支持),变异操作不应该除非这是操作的基础,否则不会返回值。因此,set.add
函数会返回一个值,但pop()
会返回list.sort()
,即使用户返回None
时偶尔也会有用。
我想你可以这样做:
self
当然,纯粹的猜测是重复的哈希查找是任何一种问题:我通常会用原始代码中的def deduped(iterable):
seen = set()
count = 0
for value in iterable:
seen.add(value)
if count != len(seen):
count += 1
yield value
for number in deduped(number_list):
# process number
测试来编写这些函数中的任何一个,并且函数的目的是简化调用代码,而不是避免多余的哈希查找。
答案 2 :(得分:0)
你为什么不做number_set.add(number)
? setdefault的意思是它不会覆盖密钥的现有值(如果存在)。但是一个集合没有值,只有一个键,所以覆盖是无关紧要的。
答案 3 :(得分:0)
setdefault
没有sets
类型方法,但您可以这样做:
number_list = [1,5,7,2,4,4,1,3,8,5]
number_set = set()
for number in number_list:
if number not in number_set and not number_set.add(number):
#do somethihng here
仅当not number_set.add(number)
为number not in number_set
时才会调用True
条件。
使用此功能,您可以按顺序处理唯一项目(保留订单)。
>>> number_list = [1,5,7,2,4,4,1,3,8,5]
>>> seen = set()
>>> [x for x in number_list if x not in seen and not seen.add(x)]
[1, 5, 7, 2, 4, 3, 8]
如果订单无关紧要,请拨打set()
上的number_list
:
>>> set(number_list)
{1, 2, 3, 4, 5, 7, 8}