【问题标题】:finding sum of values in a nested dictionary in python在python的嵌套字典中查找值的总和
【发布时间】:2013-07-01 15:18:30
【问题描述】:

我有大约 20000 个文本文件,编号为 5.txt、10.txt 等等..

我将这些文件的文件路径存储在我创建的列表“list2”中。

我还有一个包含 500 个单词的文本文件“temp.txt”

vs
mln
money

等等..

我将这些单词存储在我创建的另一个列表“列表”中。

现在我创建一个嵌套字典 d2[file][word]=“file”中“word”的频率计数

现在,

我需要为每个文本文件遍历这些单词,

我正在尝试获得以下输出:

filename.txt- sum(d[filename][word]*log(prob))

这里,filename.txt 的格式为 5.txt、10.txt 等等...

“prob”,这是我已经得到的值

我基本上需要找到每个外键(文件)的内键(单词)值的总和(即单词的频率)。

说:

d['5.txt']['the']=6

这里“the”是我的话,“5.txt”是文件。现在 6 是“the”在“5.txt”中出现的次数。

同样:

d['5.txt']['as']=2.

我需要找到字典值的总和。

所以,这里是 5.txt:我需要我的答案是:

6*log(prob('the'))+2*log(prob('as'))+...`(for all the words in list)

我需要对所有文件执行此操作。

我的问题在于我应该遍历嵌套字典的部分

import collections, sys, os, re

sys.stdout=open('4.txt','w')
from collections import Counter
from glob import glob

folderpath='d:/individual-articles'
folderpaths='d:/individual-articles/'
counter=Counter()
filepaths = glob(os.path.join(folderpath,'*.txt'))


#test contains: d:/individual-articles/5.txt,d:/individual,articles/10.txt,d:/individual-articles/15.txt and so on...
with open('test.txt', 'r') as fi:
    list2= [line.strip() for line in fi]


#temp contains the list of words
with open('temp.txt', 'r') as fi:
    list= [line.strip() for line in fi]


#the dictionary that contains d2[file][word]
d2 =defaultdict(dict)
for fil in list2:
    with open(fil) as f:
       path, name = os.path.split(fil)
       words_c = Counter([word for line in f for word in line.split()])
       for word in list:
           d2[name][word] = words_c[word]



#this portion is also for the generation of dictionary "prob",that is generated from file 2.txt can be overlooked!
with open('2.txt', 'r+') as istream:
for line in istream.readlines():
    try:
        k,r = line.strip().split(':')
        answer_ca[k.strip()].append(r.strip())
    except ValueError:
        print('Ignoring: malformed line: "{}"'.format(line))




#my problem lies here
items = d2.items()
small_d2 = dict(next(items) for _ in range(10))
for fil in list2:
    total=0
    for k,v in small_d2[fil].items():
        total=total+(v*answer_ca[k])
    print("Total of {} is {}".format(fil,total))

【问题讨论】:

  • float(d2[fil].values()) : dict.values 返回一个列表而不是数字,所以在它上面应用float() 也是一个错误。
  • 是的,我已经纠正了它!但是 keyerror 仍然存在
  • 老实说,我不知道你在问什么。您能否发布一个 minimal 代码示例来说明您的问题?
  • 尽量将您发布的代码保持在最低限度。让你展示的每一行都能真正说明你的问题。当问题可以在 10 中显示时,没有人愿意阅读 50 多行代码。
  • @SlaterTyranus:说,d['the']['5.txt']=6,这里“the”是我的话,“5.txt”是文件。现在 6 是“the”出现在“5.txt”中的次数。类似地,d['as']['5.txt']=2。我有大约 100 个文件,对于每个文件,我需要找到总和字典值。所以,这里是 5.txt:我需要我的答案是“6+2=8”。我需要对所有文件都这样做。

标签: python dictionary python-3.x machine-learning python-3.3


【解决方案1】:

with open(f) as fil 将 fil 分配给 f 的任何内容。当您以后访问字典中的条目时,

total=sum(math.log(prob)*d2[fil][word].values())

我相信你的意思

total = sum(math.log(prob)*d2[f][word])

不过,这似乎与您期望的顺序不太匹配,因此我建议您改为:

word_list = [#list of words]
file_list = [#list of files]
dictionary = {#your dictionary}
summation = lambda file_name,prob: sum([(math.log(prob)*dictionary[word][file_name]) for word in word_list])
return_value = []
for file_name in file_list:
    prob = #something
    return_value.append(summation(file_name))

那里的求和行是在 python 中定义一个匿名函数。这些被称为 lambda 函数。本质上,该行的具体含义是:

summation = lambda file_name,prob:

几乎等同于:

def summation(file_name, prob):

然后

sum([(math.log(prob)*dictionary[word][file_name]) for word in word_list])

几乎等同于:

result = []
for word in word_list:
    result.append(math.log(prob)*dictionary[word][file_name]
return sum(result)

所以你总共有:

    summation = lambda file_name,prob: sum([(math.log(prob)*dictionary[word][file_name]) for word in word_list])

代替:

def summation(file_name, prob):
    result = []
    for word in word_list:
        result.append(math.log(prob)*dictionary[word][file_name])
    return sum(result)

虽然带有列表推导的 lambda 函数比 for 循环实现要快得多。在 python 中,很少有人应该使用 for 循环而不是列表推导式,但它们确实存在。

【讨论】:

  • 我在这一行得到一个类型错误:summation = lambda file_name, prob: sum([math.log(prob)*dictionary[word]["file_name"] for word in word_list]),它说:(lambda)()缺少1个必需的位置参数:'prob'
  • line:summation = lambda file_name, prob: sum([math.log(prob)*dictionary[word]["file_name"] for word_list]) 是什么意思?
  • @PokerFace 我想 keyerror 是因为不会有任何与文件内容相等的键,因为那是一些奇怪的长字符串。因此f 而不是fil
  • 在这一行:return sum(result),为什么说语法无效?我用的是python 3
  • @PokerFace 哦,上面一行缺少括号。
【解决方案2】:
for fil in list2:  #list2 contains the filenames
    total = 0
    for k,v in d[fil].iteritems():
        total += v*log(prob[k])  #where prob is a dict

    print "Total of {} is {}".format(fil,total)

【讨论】:

  • 但我需要总和为 (dic.values()*log(prob)).. 它不起作用,因为它是不受支持的操作数类型
  • @PokerFace 我建议你发布一些示例数据和预期输出,因为这个问题非常不清楚。
  • 很抱歉,我现在已经编辑了我的代码,请您现在检查一下,希望它清楚!
  • 每个单词都有一个相关的概率“prob”,所以在这里,我是否应该将 prob(k) 视为键值为 k=word 的字典?
  • @PokerFace 是的,dict 将成为这里最好的数据结构,word: prob 对。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
相关资源
最近更新 更多