集合中是否存在'dict.setdefault'等价物?

时间:2013-10-27 19:47:05

标签: python dictionary

使用集合时的常见模式如下:

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)):这样的东西,但名字更好。

4 个答案:

答案 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}