首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python -函数类似于dict.get,但返回的是默认键值而不是默认值?

Python -函数类似于dict.get,但返回的是默认键值而不是默认值?
EN

Stack Overflow用户
提问于 2018-03-22 18:14:29
回答 3查看 76关注 0票数 3

比方说

代码语言:javascript
运行
复制
a = {1:2, 3:4, 5:6}

有没有内置函数(可能是类似a.get2(7,5))的函数,返回a[7];如果a[7]不存在,则返回a[5]?)

这类函数可以很容易地定义为a.get(val, a.get(def_key)),但如果存在,则更倾向于使用内置解决方案。

EN

回答 3

Stack Overflow用户

发布于 2018-03-22 18:24:09

您可以子类化dict

代码语言:javascript
运行
复制
class MyDict(dict):
    def get2(self,*keys):
        for k in keys:
            if k in self:
                return self.get(k)
        return None  # if not found

a = {1:2, 3:4, 5:6}
b = MyDict(a)
print(b.get2(2,10,5))

位置参数允许将行为扩展到n个键。一般情况下,不能使用get来知道关键字是否在字典中,因为一些值可能为None,因此需要进行in测试。

避免使用sentinel对象进行双重判定测试

代码语言:javascript
运行
复制
class MyDict(dict):
    __notfound = object()
    def get2(self,*keys):
        for k in keys:
            x = self.get(k,self.__notfound )
            if x is not self.__notfound :
               return x
        return None  # if not found
票数 2
EN

Stack Overflow用户

发布于 2018-03-22 18:18:54

可以设置常量回退值。一种方法是使用collections.defaultdict

注意:这需要创建一个新的字典。当然,我们可以将其赋给相同的变量。

代码语言:javascript
运行
复制
from collections import defaultdict

a = {1:2, 3:4, 5:6}

a = defaultdict(lambda: a[5], a)

这会将默认值设置为常量6,该常量将在找不到密钥时返回。如果需要,您必须在每次更新a[5]时重置您的默认值。

票数 1
EN

Stack Overflow用户

发布于 2018-03-23 08:53:30

您可以定义dict的子类来访问具有虚拟默认值的字典条目,该值将应用于任何不存在的键,但在引用它们时不会实际创建任何键(与setdefault()函数相反)

代码语言:javascript
运行
复制
 class dictWithDefault(dict):
     def __init__(self,aDict={},defaultValue=None):
         super().__init__(aDict)
         def aFunction():pass
         self._default = defaultValue if type(defaultValue) == type(aFunction) else lambda : defaultValue
     def __getitem__(self,key):
         return super().__getitem__(key) if key in self else self._default()

 d = {1:2, 3:4, 5:6}

 d = dictWithDefault(d,99)
 d[1] # >>> 2
 d[7] # >>> 99  this is the default value, but key 7 still doesn't exist
 d[7] = 97
 d[7] # >>> 97 once assigned the key has its own value
 d._default = 100 # you can change the virtual default at any time
 d[9] # >>> 100
 d[8] += 5   # this can be useful when key/values are used to count things
             # (using a default value of zero) akin to a Bag structure
 d[8] # >>> 105
 d    # >>> {1: 2, 3: 4, 5: 6, 7: 97, 8: 105}

您也可以直接使用默认值创建字典:

代码语言:javascript
运行
复制
d = dictWithDefault({1:2, 3:4, 5:6},99)

要使用缺省键而不是缺省值,您可以使用相同的技术,只需更改getitem方法的实现。

或者,您可以简单地使用不带默认值的d= dictWithDefault(d),并使用运算符来获得可选键:

代码语言:javascript
运行
复制
d = dictWithDefault(d)
value = d[7] or d[5]

编辑更改了代码,以支持将对象作为默认值。

在使用对象(例如列表)作为字典的值时,您必须注意这一点。在第一次对新键进行隐式赋值时,它只会被赋值一个对_default对象的引用。这意味着所有这些键最终都会引用同一个对象。

例如:d= dictWithDefault(defaultValue=[])将不会按预期工作。

代码语言:javascript
运行
复制
d = dictWithDefault(defaultValue=[])

d["A"].append(1)
d["B"].append(2)

# will end up with { "A":[1,2], "A":[1,2] } 
# because both keys (A and B) reference the same list instance.

为了解决这个问题,我更改了函数,以便它可以接受lambda:在将对象用作默认值的情况下。

这允许默认值在用于新密钥时创建新实例。

代码语言:javascript
运行
复制
d = dictWithDefault(defaultValue=lambda:[])

d["A"].append(1)
d["B"].append(2)

# now works properly giving: { "A":[1], "B":[2] }

对于简单类型(字符串、整数等),您仍然可以使用不带lambda的类。但是,当字典将对象存储为值时,您必须确保将lambda:与实例创建方法一起使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49425941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档