Python:如何在字典中获取特定键前所有值的总和
我刚开始学习Python,对字典操作有些疑问。
我正在维护一个字典,内容如下 -
dict = {counter:distance}.
举个例子 -
dict = {1:1, 2:10, 3:27, 4:10, 5:7, 6:10}
对于一个给定的键,我想找到到达这个键的总距离。
比如说,给定键是5,那么返回的总距离应该是 (1+10+27+10) = 48。
我想出了一个简单的解决方案,如下 -
input_key = raw_input()
dist = 0
for key,value in dict:
if key == input_key
break
else
dist += value
return dist
我在寻找一些内置的函数或库,想用它们来实现这个功能。
我的需求是,我要把数据写入一个输出文件。格式如下 - docid \t termid \t number
100\t2943\t3
我有一些循环,分别针对每个docid和termid进行处理。termid在循环中可能会重复,这样的话我需要修改输出文件中的那一行。因此,如果docid是100,termid是2943,再次遇到时number变成58,那么上面的那一行就需要改成 -
100\t2943\t3\t58
这样,输出文件中的同一行可以根据docid和termid多次修改。
我想减少在输出文件中搜索'^docid\ttermid'模式并修改那一行所花费的时间。因此,我打算维护一个字典,用来保存输出文件中的偏移量。这样我就可以遍历字典,获取文件中的偏移量,读取那一行并进行修改。
6 个回答
也许可以这样做:
input_key = int(raw_input())
dist = sum(dict[i] for i in xrange(1, input_key))
举个例子:
>>> dict = {1:1, 2:10, 3:27, 4:10, 5:7, 6:10}
>>> sum(dict[i] for i in xrange(1, 5))
48
请注意,你提供的代码可能无法稳定运行,因为在字典对象中,键的顺序是没有定义的;也就是说,键值对的顺序可能会以任何顺序出现。这个回答中的代码会遍历从1到input_key
- 1的数字,并将这些键在字典中存储的值相加。
首先,你需要对字典进行排序。你可以使用一种叫做 OrderedDict 的工具来实现这个功能。
下面是一个例子:
import collections
input_key = int(raw_input()) # In this example I suppose is 5
dict = {1:1, 2:10, 3:27, 4:10, 5:7, 6:10}
od = collections.OrderedDict(sorted(dict.items()))
In: sum(od[m] for m in filter(lambda x: x<input_key, od))
Out: 48
>>> from operator import itemgetter
>>> d = {1:1, 2:10, 3:27, 4:10, 5:7, 6:10}
>>> sum((x[1] for x in sorted(d.items(), key=itemgetter(0)) if x[0] < 5))
48
注意事项:
dict
(字典)不是一种有序的数据结构,也就是说里面的元素顺序是不固定的。sorted
和.items()
用来给我们一个有序的(计数, 距离)
的序列。- 这是一个生成器表达式,最后会通过
sum()
来计算总和。 - 这里使用一个
list
(列表)来存放tuple
(元组)会更好,比如:[(1, 1), (2, 10), ...]
作为一个函数:
def distance(d, k):
return sum((x[1] for x in sorted(d.items(), key=itemgetter(0)) if x[0] < k))
字典(Dictionary)并不是一种有序的映射结构。如果你想要有序的映射,可以使用其他的序列数据结构,或者使用 collections.OrderedDict
。
另外,遍历字典的时候,得到的不是键值对,而只是键。
下面是一个使用 itertools.takewhile
的解决方案:
>>> import itertools
>>> from collections import OrderedDict
>>>
>>> d = OrderedDict([(1,1), (2,10), (3,27), (4,10), (5,7), (6,10)])
>>> print sum(map(d.get, itertools.takewhile(lambda key: key != 5, d)))
48