为不存在的对象属性赋值

2024-04-20 07:00:16 发布

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

我正在用python(2.7)做数据挖掘作业。我为所有单词(存在于类别中)创建了一个权重dict,对于这个dict中不存在的单词,我想指定一个默认值。 首先,在使用之前,我尝试了everykey的setdefault,它工作得很好,但不知怎么的,我觉得它看起来不太像pythonic。因此,我尝试使用defaultdict,它在大多数情况下都可以正常工作。但是,有时它会返回不正确的值。首先我认为它可能是由defaultdict或lambda函数引起的,但显然没有错误。你知道吗

for node in globalTreeRoot.traverse():
    ...irrelevant...
    weight_dict = {.......}
    default_value = 1.0 / (totalwords + dictlen)
    node.default_value = 1.0/ (totalwords + dictlen)
    ......
    node.weight_dict_ori = weight_dict
    node.weight_dict = defaultdict(lambda :default_value,weight_dict)

所以,当我试图打印一个在循环中不存在的值时,它给了我一个正确的值。但是,在代码运行完成后,当我尝试:

print node.weight_dict["doesnotexist"],

它给我一个不正确的值,当不正确时,通常是一个与其他节点相关的值。我尝试搜索python命名系统动态地为对象属性赋值,但没有找到答案。你知道吗

顺便问一下,defaultdict是否比每次使用setdefault(k,v)都快?你知道吗


Tags: lambda数据挖掘nodedefaultvalue作业类别单词
3条回答

setdefault绝对是您应该用来设置默认值的。你知道吗

for node in globalTreeRoot.traverse():
    node.default_value = 1.0 / (totalwords + dictlen)
    node.weight_dict = {}
    # if you did want to use a defaultdict here for some reason, it would be
    #   node.weight_dict = defaultdict(lambda: node.default_value)
    for word in wordlist:
        value = node.weight_dict.setdefault(word, node.default_value)

显然,defaultdict有问题。你知道吗

d1 = {"a":10,"b":9,"c":8}
seven = 7
d2 = defaultdict(lambda :seven,d1)
seven = 8
d3 = defaultdict(lambda :seven,d1)

结果是:

>>> d2[4234]
8

我还是不明白为什么会这样。至于我的工作,我将坚持使用setdefault。你知道吗

更新: 谢谢你的回答。我误解了变量作用域在Python中的工作方式。你知道吗

这不是defaultdict的用例。你知道吗

相反,只需使用get从字典中获取值。你知道吗

val = dict.get("doesnotexist", 1234321)

是完全可以接受的python“get”还有第二个参数,如果找不到键,则为默认值。你知道吗

如果你只需要这个“获取”,defaultdict有点过分了。它的用法如下:

example = defaultdict(list)
example[key].append(1)

无需每次都显式初始化键列表组合。对于数值,改进是微不足道的:

ex1, ex2 = dict, defaultdict(lambda: 0)
ex1[key] = ex1.get(key, 0) + 1
ex2[key] += 1

最初的问题可能是因为重用了存储权重的变量。确保它是本地到循环!你知道吗

var = 1
ex3 = defaultdict(lambda: var)
var = 2
print ex3[123]

应该返回var=2的当前值。它在初始化时不会被替换到字典中,但它的行为就像您在此位置定义了一个函数,访问“outer”变量var

黑客是这样的:

def constfunc(x):
  return lambda: x
ex3 = defaultdict(constfunc(var))

现在constfunc是在初始化时计算的,x是调用的局部变量,lambda现在将返回一个不再改变的x。我想你可以内联这个(未经测试):

ex3 = defaultdict((lambda x: lambda: x)(var))

瞧,Python的魔力,捕捉“闭包”和命令式语言假装做函数式编程的异常现象。你知道吗

相关问题 更多 >