0

我有 2 个列表(“IDS”和“支付”)。IDS 的 len 是 50000,Pay 的 len 是 650000 IDS 是 IDS 的列表,如 [1,2,3,4,5,6 ... ] 并且 PAY 列表是包含所有付款的列表的列表IDS 所做的,例如 [ [1,50], [1,100], [1,60], [2,50], [2,80], [2,50], ...]

要知道每个 ID 总共支付了多少,我在另一个 for 循环中进行了一个 for 循环,如下所示:

for x in IDS:
    total = 0
    for i in xrange(0,len(Pay)):
        if x == Pay[i][0]:
            total += Pay[i][1]
    print x + str(total)

但是处理这个需要很长时间!我曾尝试将 Pay 分成 10 份,但仍然花费了太长时间。有人对如何改进此操作有一些想法吗?

谢谢!

4

4 回答 4

3

您可以使用collections.Counter

>>> from collections import Counter
>>> pay = [ [1,50], [1,100], [1,60], [2,50], [2,80], [2,50]]
>>> c = Counter()
>>> for idx, amt in pay:
    c[idx] += amt
...     
>>> c
Counter({1: 210, 2: 180})
于 2013-09-18T14:44:17.603 回答
2

好的,事实是你有 2 个很长的列表。与其讨论使用什么库,不如讨论一个更好的算法?

IDs 自然应该包含唯一的整数(我猜),而 Pay 是 (id, payment) 的元组。

现在想想你的名单来自哪里。有两种可能:

  1. 从文件中读取

  2. 来自某些数据库,例如 MySQL

如果是选项 1,则应改为执行以下操作:

from collections import defaultdict
totals = defaultdict(someObj_factory)
[totals[int(line.split[0])].accumulate(someObj_factory(line.split()[1]))
 for line in paymentFile]

首先,您不需要将 id 作为独立列表,因为您在 Pay 中拥有它们。

二是节省阅读时间。

第三,对于脚本语言,列表理解节省了解释时间。

第四,这是健壮的,因为您可以添加任何您想要的对象,例如日期或元组。

如果是选项 2,请在您的数据库中进行计数-.-

另一种选择是将这些插入数据库,并在那里进行计数。MySQL 等就是为这种任务而设计的。你会惊讶于它的效率。更多信息: http: //mysql-python.sourceforge.net/

于 2013-09-18T16:36:59.603 回答
0

您只需要迭代Pay一次(而不是 50000 次!)。您可以通过散列显着加快计算速度:

totals = dict(map(lambda id: (id,0), IDS))

for L in Pay:
    if L[0] in totals:
        totals[L[0]] = totals[L[0]] + L[1]


for (id, total) in totals.iteritems():
    print "id: %s, total: %d"%(id, total)
于 2013-09-18T14:57:38.760 回答
0

如果collections.Counter对你不起作用——比如你使用的是不同的 Python 版本——将你的工资单转换成字典也会产生同样的效果。

totals = {}
for id, amount in pay:
   totals[id] = totals.setdefault(id, 0) + amount

就像付款日期 [1,50,2013-09-01] 一样,我只需要对大于 '2013-01-01' 的日期的值求和吗?

然后这样做:

import datetime

base_date = datetime.datetime.strptime('2013-01-01', '%Y-%m-%d').date()

totals = {}
for idx, amount, pay_date in pay:
   if datetime.datetime.strptime(pay_date, '%Y-%m-%d').date() > base_date:
       totals[idx] = totals.setdefault(id, 0) + amount
于 2013-09-18T14:47:38.743 回答