Python中的列表操作
我有一个包含子列表的列表。例如:([1, 2], [1, 56], [2, 787], [2, 98], [3, 90]
),这个列表是在一个循环中通过添加值创建的。
我在用Python编程,我想把每个子列表中第一个元素相同的第二个元素加起来。在我的例子中:我想把2和56加起来(它们的第一个元素都是1),把787和98加起来(它们的第一个元素都是2),而90保持不变,因为只有一个元素的第一个元素是3。
我不太确定该怎么做。
这是我的代码:
import urllib, re
from itertools import groupby
import collections
import itertools, operator
text = urllib.urlopen("some html page").read()
data = re.compile(r'.*?<BODY>(.*?)<HR>', re.DOTALL).match(text).group(1)// storing contents from the BODY tag
values = [line.split() for line in data.splitlines()] //List with the BODY data
/* values contain elements like [[65, 67], [112, 123, 12], [387, 198, 09]]
it contains elements with length 2 and three.
i am just concerned with elements with length 3
in the for loop, i am doing this, and passing it to 2 functions.*/
def function1 (docid, doclen, tf):
new=[];
avgdoclen = 288;
tf = float(x[2]);
doclen = float(x[1]);
answer1 = tf / (tf + 0.5 + (1.5*doclen/avgdoclen));
q = function2(docid, doclen, tf)
production = answer1 * q //this is the production of
new.append(docid) // i want to add all the production values where docid are same.
new.append(production)
return answer1
def function2 (docid, doclen, tf):
avgdoclen = 288;
querylen = 12;
tf= float(x[2]);
answer2 = tf/(tf + 0.5 + (1.5*querylen/avgdoclen));
return answer2
for x in values:
if len(x)==3:
okapi_doc(x[0], x[1], x[2])
okapi_query(x[0], x[1], x[2])
我想把所有相同docid的生产值加起来。现在当我打印new时,得到的输出是:
['112', 0.3559469323909391]
['150', 0.31715060007742935]
['158', 0.122025819265144]
['176', 0.3862207694241891]
['188', 0.5057900225015092]
['236', 0.12628982528263102]
['251', 0.12166336633663369]
这不是一个列表。当我打印new[0][0]时,我得到1。我想要的是112,当我打印new[0][0]时。append是不是有什么问题?
['334', 0.5851519557155408]4 个回答
这很简单。dict.get(key, default)
这个方法会返回指定的键对应的值,如果这个键不存在,就会返回一个默认值。
totals = {}
for k,v in data:
totals[k] = totals.get(k, 0) + v
这可能是用 itertools 来解决的问题:
>>> import itertools, operator
>>> l = sorted([[1, 2], [1, 56], [2, 787], [2, 98], [3, 90]])
>>> keys_groups = itertools.groupby(l, key=operator.itemgetter(0))
>>> sums = [[key, sum(i[1] for i in group)] for key, group in keys_groups]
>>> sums
[[1, 58], [2, 885], [3, 90]]
注意,要让 groupby
正常工作,列表里的项目必须按照给定的关键字排序。在这个例子中,因为关键字是每对中的第一个项目,所以我不需要排序,但如果你想要一个更通用的解决方案,应该使用 key
参数来对列表进行排序。
>>> l2 = [[787, 2], [98, 2], [90, 3], [2, 1], [56, 1]]
>>> l2.sort(key=operator.itemgetter(1))
>>> l2
[[2, 1], [56, 1], [787, 2], [98, 2], [90, 3]]
>>> keys_groups = itertools.groupby(l2, key=operator.itemgetter(1))
>>> sums = [[key, sum(i[0] for i in group)] for key, group in keys_groups]
>>> sums
[[1, 58], [2, 885], [3, 90]]
这个方法在你提供的数据上运行得很好。我稍微修改了一下,让这个例子看起来更真实。
>>> l = [['112', 0.3559469323909391], ['150', 0.31715060007742935],
['158',0.122025819265144], ['176', 0.3862207694241891],
['188', 0.5057900225015092], ['377', 0.12628982528263102],
['251', 0.12166336633663369], ['334', 0.5851519557155408],
['334', 0.14663484486873507], ['112', 0.2345038167938931],
['377', 0.10694516971279373], ['112', 0.28981132075471694]]
>>> l.sort(key=operator.itemgetter(0))
>>> keys_groups = itertools.groupby(l, key=operator.itemgetter(0))
>>> sums = [[key, sum(i[1] for i in group)] for key, group in keys_groups]
>>> sums
[['112', 0.88026206993954914], ['150', 0.31715060007742935],
['158', 0.122025819265144], ['176', 0.38622076942418909],
['188', 0.50579002250150917], ['251', 0.12166336633663369],
['334', 0.73178680058427581], ['377', 0.23323499499542477]]
注意,正如 WolframH 指出的,排序通常会增加时间复杂度;不过 Python 的排序算法很聪明,可以利用数据中的顺序,所以可能不会增加复杂度——这完全取决于数据本身。不过,如果你的数据是高度反向排序的,Winston Ewert 提出的基于 defaultdict
的解决方案可能会更好。(不过忽略那个第一个 Counter
的代码片段——我对那部分不太了解。)
关于如何创建列表,有很多方法,但在 Python 中有两种基本的方法——第一种是列表推导:
>>> def simple_function(x):
... return [x, x ** 2]
...
>>> in_data = range(10)
>>> out_data = [simple_function(x) for x in in_data]
>>> out_data
[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
第二种是使用 for 循环:
>>> out_data = []
>>> for x in in_data:
... out_data.append(simple_function(x))
...
>>> out_data
[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在另一个地方使用这些数据。这个过程就像是把水从一个桶倒到另一个桶一样。
有些时候,我们会遇到一些问题,比如数据的格式不对,或者数据的类型不匹配。这就像是你想把牛奶倒进一个只适合倒水的杯子里,这样就会出问题。
为了避免这些问题,我们需要确保在处理数据之前,先检查一下数据的类型和格式。这就像是在倒水之前,先确认一下桶是不是干净的,能不能用。
总之,处理数据的时候,保持谨慎,确保每一步都是正确的,这样才能顺利完成任务。
import collections
result = collections.defaultdict(int) # works like a dictionary
# but all keys have a default value of zero
for key, value in mylist:
result[key] += value
print result