Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 里面大,里面大。我怎样才能减少时间?_Python_Loops_For Loop_Logic - Fatal编程技术网

Python 里面大,里面大。我怎样才能减少时间?

Python 里面大,里面大。我怎样才能减少时间?,python,loops,for-loop,logic,Python,Loops,For Loop,Logic,我有两个列表(“ID”和“付款”)。ID的长度为50000,工资的长度为650000 IDS是一个ID列表,如[1,2,3,4,5,6…],付款列表是一个包含IDS所做的所有付款的列表,如[[1,50]、[1100]、[1,60]、[2,50]、[2,80]、[2,50]、…] 为了知道每个ID总共支付了多少钱,我在另一个for循环中做了一个for循环,如下所示: for x in IDS: total = 0 for i in xrange(0,len(Pay)):

我有两个列表(“ID”和“付款”)。ID的长度为50000,工资的长度为650000 IDS是一个ID列表,如[1,2,3,4,5,6…],付款列表是一个包含IDS所做的所有付款的列表,如[[1,50]、[1100]、[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)
但这需要花费很多时间来处理! 我试着把工资分成10份,但还是花了太长时间。 有人知道我该如何改进这个操作吗


谢谢大家!

您可以使用
集合。计数器

>>> 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})

您可以使用集合。计数器

>>> 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})

如果
collections.Counter
对您不起作用,比如说,如果您使用的是不同的Python版本,那么将您的薪资列表转换为字典将具有相同的效果

totals = {}
for id, amount in pay:
   totals[id] = totals.setdefault(id, 0) + amount
如付款日期[1,502013-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

如果
collections.Counter
对您不起作用,比如说,如果您使用的是不同的Python版本,那么将您的薪资列表转换为字典将具有相同的效果

totals = {}
for id, amount in pay:
   totals[id] = totals.setdefault(id, 0) + amount
如付款日期[1,502013-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

您只需要迭代
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)

您只需要迭代
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)

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

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

现在想想你的清单是从哪里来的。有两种可能性:

  • 从文件中读取

  • 从一些数据库,比如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作为一个独立的列表,因为你有他们在支付

    其次,它节省了阅读时间

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

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

    如果是选项2,则在数据库中进行计数--


    另一个选项是将这些数据插入数据库,并在其中进行计数。MySQL等都是为这种任务而设计的。你会惊讶于它的效率。更多信息:

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

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

    现在想想你的清单是从哪里来的。有两种可能性:

  • 从文件中读取

  • 从一些数据库,比如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作为一个独立的列表,因为你有他们在支付

    其次,它节省了阅读时间

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

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

    如果是选项2,则在数据库中进行计数--



    另一个选项是将这些数据插入数据库,并在其中进行计数。MySQL等都是为这种任务而设计的。你会惊讶于它的效率。更多信息:

    使用dict进行支付{IDS:IDSmult}~O(1)代替O(n)用dict来支付怎么样?比如Pay={1:[50100,60]},2:[50,80,50,…。如果使用dict,你也可以删除ID。使用dict进行Pay{IDS:IDSmult}。~O(1)而不是O(n)如何使用dict进行支付?比如Pay={1:[50100,60]},2:[50,80,50,…。如果使用dict,你也可以删除ID。很好,不知道收款!但是如果“Pay”列表中有更多信息,如付款日期[1,502013-09-01],我只需对大于'2013-01-01'的日期的值求和?@Antonio只需添加一个
    if
    条件:
    对于idx,amt,dt in pay:if dt>2013-09-01:c[idx]+=amt
    。(别忘了使用
    datetime.datetime.strtime
    将日期字符串转换为datetime对象)@Antonio:如果这对你有效,你应该接受这个解决方案=DNice,不知道收款!但是如果“付款”列表有更多信息,比如付款日期[1,502013-09-01]而且我必须只对大于'2013-01-01'的日期的值求和?@Antonio只需添加一个
    if
    条件:
    对于idx,amt,dt in pay:if dt>2013-09-01:c[idx]+=amt
    (别忘了使用
    datetime.datetime.strtime
    将日期字符串转换为datetime对象)@安东尼奥:如果这对您有效,您应该接受此解决方案=DDon不要使用
    id
    作为变量名。不要使用
    id
    作为变量名。如果
    Pay[i][0]
    for all
    i
    id
    中,那么您可以通过省略包含检查来进一步优化,即
    如果L[0]总计
    。即使您不能散列,这种迭代方式仍然是优越的,因为它可能会最大化缓存命中率。如果
    Pay[i][0]
    for all
    i
    IDS
    中,那么您可以通过省略包含检查来进一步优化,即
    if L[0]在totals中
    。即使您不能散列,这种迭代方式仍然是优越的,因为它可能会最大化缓存命中率。