“setdefault”dict方法的用例

2024-04-29 02:19:45 发布

您现在位置:Python中文网/ 问答频道 /正文

Python 2.5中添加的collections.defaultdict大大减少了对dictsetdefault方法的需要。这个问题是为了我们的集体教育:

  1. 今天在Python 2.6/2.7中,setdefault还有什么用处?
  2. 哪些流行的setdefault用例被collections.defaultdict取代?

Tags: 方法用例collectionsdict用处集体defaultdictsetdefault
3条回答

我通常对关键字参数dict使用setdefault,例如在这个函数中:

def notify(self, level, *pargs, **kwargs):
    kwargs.setdefault("persist", level >= DANGER)
    self.__defcon.set(level, **kwargs)
    try:
        kwargs.setdefault("name", self.client.player_entity().name)
    except pytibia.PlayerEntityNotFound:
        pass
    return _notify(level, *pargs, **kwargs)

它非常适合在包装器中调整接受关键字参数的函数的参数。

可以说,defaultdict在填充dict之前对设置默认值很有用,setdefault在填充dict时或之后对设置默认值很有用。

可能是最常见的用例:分组项(在未排序的数据中,否则使用itertools.groupby

# really verbose
new = {}
for (key, value) in data:
    if key in new:
        new[key].append( value )
    else:
        new[key] = [value]


# easy with setdefault
new = {}
for (key, value) in data:
    group = new.setdefault(key, []) # key might exist already
    group.append( value )


# even simpler with defaultdict 
new = defaultdict(list)
for (key, value) in data:
    new[key].append( value ) # all keys have a default already

有时您希望确保在创建dict之后存在特定的键。defaultdict在这种情况下不起作用,因为它只在显式访问时创建键。假设您使用了带有许多头的HTTP-ish——有些是可选的,但您希望它们具有默认值:

headers = parse_headers( msg ) # parse the message, get a dict
# now add all the optional headers
for headername, defaultvalue in optional_headers:
    headers.setdefault( headername, defaultvalue )

defaultdict当默认值是静态的(比如一个新列表)时非常好,但如果它是动态的,就不那么好了。

例如,我需要一个字典来将字符串映射到唯一的int。defaultdict(int)将始终使用0作为默认值。同样,defaultdict(intGen())总是产生1。

相反,我用了一个常规的口述:

nextID = intGen()
myDict = {}
for lots of complicated stuff:
    #stuff that generates unpredictable, possibly already seen str
    strID = myDict.setdefault(myStr, nextID())

注意dict.get(key, nextID())是不够的,因为我以后也需要能够引用这些值。

intGen是我构建的一个小类,它自动递增一个int并返回其值:

class intGen:
    def __init__(self):
        self.i = 0

    def __call__(self):
        self.i += 1
    return self.i

如果有人能用defaultdict来做这件事,我很想看看。

相关问题 更多 >