Python-计算列表中日期的出现次数

时间:2015-10-11 18:56:33

标签: python list datetime count counter

我有一个缺陷列表,其中包含缺陷日期,缺陷的优先​​级以及缺陷所在的冲刺以及缺陷存在的月份。我想计算优先级1,2,3和总数列表中每个日期的缺陷。 目前我正在使用它来识别总缺陷,但这种逻辑似乎不起作用。如果有人可以帮我这个。

import datetime
#this is my defect list 
defectdetails = 
[[datetime.datetime(2015, 1, 1, 0, 0), 1, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 3, 0, 0), 2, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 6, 0, 0), 1, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 10, 0, 0), 1, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 16, 0, 0), 2, 'Sprint 2', 'January 2015'], [datetime.datetime(2015, 2, 18, 0, 0), 3, 'Sprint 4', 'February 2015'], [datetime.datetime(2015, 3, 3, 0, 0), 1, 'Sprint 5', 'March 2015'], [datetime.datetime(2015, 3, 7, 0, 0), 1, 'Sprint 5', 'March 2015'], [datetime.datetime(2015, 3, 9, 0, 0), 3, 'Sprint 5', 'March 2015'], [datetime.datetime(2015, 4, 5, 0, 0), 1, 'Sprint 7', 'April 2015'], [datetime.datetime(2015, 4, 15, 0, 0), 2, 'Sprint 7', 'April 2015'], [datetime.datetime(2015, 4, 25, 0, 0), 1, 'Sprint 8', 'April 2015'], [datetime.datetime(2015, 5, 9, 0, 0), 2, 'Sprint 9', 'May 2015'], [datetime.datetime(2015, 5, 14, 0, 0), 3, 'Sprint 9', 'May 2015'], [datetime.datetime(2015, 5, 19, 0, 0), 2, 'Sprint 10', 'May 2015'], [datetime.datetime(2015, 5, 21, 0, 0), 3, 'Sprint 10', 'May 2015'], [datetime.datetime(2015, 6, 1, 0, 0), 1, 'Sprint 11', 'June 2015'], [datetime.datetime(2015, 6, 5, 0, 0), 1, 'Sprint 11', 'June 2015'], [datetime.datetime(2015, 7, 15, 0, 0), 2, 'Sprint 14', 'July 2015'], [datetime.datetime(2015, 7, 25, 0, 0), 1, 'Sprint 14', 'July 2015'], [datetime.datetime(2015, 8, 8, 0, 0), 1, 'Sprint 15', 'August 2015'], [datetime.datetime(2015, 8, 19, 0, 0), 3, 'Sprint 16', 'August 2015'], [datetime.datetime(2015, 8, 19, 0, 0), 2, 'Sprint 16', 'August 2015'], [datetime.datetime(2015, 8, 20, 0, 0), 1, 'Sprint 16', 'August 2015'],  [datetime.datetime(2015, 11, 12, 0, 0), 3, 'Sprint 22', 'November 2015'], [datetime.datetime(2015, 11, 21, 0, 0), 3, 'Sprint 22', 'November 2015'], [datetime.datetime(2015, 12, 11, 0, 0), 1, 'Sprint 23', 'December 2015'], [datetime.datetime(2015, 12, 30, 0, 0), 1, 'Sprint 25', 'December 2015'], [datetime.datetime(2015, 1, 1, 0, 0), 1, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 3, 0, 0), 2, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 1, 0, 0), 1, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 3, 0, 0), 3, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 1, 0, 0), 2, 'Sprint 1', 'January 2015'], [datetime.datetime(2015, 1, 3, 0, 0), 2, 'Sprint 1', 'January 2015']]


defectdetailscopy = list(defectdetails)

for i in range(len(defectdetails)):
    value = len(defectdetailscopy)
    for j in range(0,value,1):
         print(j)
         if (defectdetails[i][0] == defectdetailscopy[j][0]):
              count +=1
              defectdetailscopy.pop(j)
              value = len(defectdetailscopy)
     print ('the total defect for date' + str(defectdetails[i][0]) +'is '+str(count)) 

当第二个循环运行时,它会抛出索引超出范围的错误。我相信我在if条件下更新的变量值不适用于for循环,因为当我从列表中弹出元素时,循环失败,索引超出绑定错误。

3 个答案:

答案 0 :(得分:4)

您可以使用collections.Counter以及生成器表达式 -

from collections import Counter
dcounts = Counter(d[0] for d in defectdetails)
for d, count in dcounts.items():
    print('The total defects for date {} is {}'.format(d, count))

您还可以使用datetime.datetime.strftime()方法格式化日期的打印方式。示例(以DD-MM-YYY格式打印日期)print语句将变为 -

 print('The total defects for date {} is {}'.format(d.strftime('%d-%m-%Y'), count))

使用您的数据进行演示 -

>>> from collections import Counter
>>> dcounts = Counter(d[0] for d in defectdetails)
>>> for d, count in dcounts.items():
...     print('The total defects for date {} is {}'.format(d, count))
...
The total defects for date 2015-01-16 00:00:00 is 1
The total defects for date 2015-08-19 00:00:00 is 2
The total defects for date 2015-03-09 00:00:00 is 1
The total defects for date 2015-03-07 00:00:00 is 1
The total defects for date 2015-07-15 00:00:00 is 1
The total defects for date 2015-05-19 00:00:00 is 1
The total defects for date 2015-03-03 00:00:00 is 1
The total defects for date 2015-01-10 00:00:00 is 1
The total defects for date 2015-04-25 00:00:00 is 1
The total defects for date 2015-06-05 00:00:00 is 1
The total defects for date 2015-05-21 00:00:00 is 1
The total defects for date 2015-02-18 00:00:00 is 1
The total defects for date 2015-11-21 00:00:00 is 1
The total defects for date 2015-05-14 00:00:00 is 1
The total defects for date 2015-12-30 00:00:00 is 1
The total defects for date 2015-07-25 00:00:00 is 1
The total defects for date 2015-05-09 00:00:00 is 1
The total defects for date 2015-11-12 00:00:00 is 1
The total defects for date 2015-04-05 00:00:00 is 1
The total defects for date 2015-01-03 00:00:00 is 4
The total defects for date 2015-04-15 00:00:00 is 1
The total defects for date 2015-01-01 00:00:00 is 4
The total defects for date 2015-06-01 00:00:00 is 1
The total defects for date 2015-08-08 00:00:00 is 1
The total defects for date 2015-08-20 00:00:00 is 1
The total defects for date 2015-01-06 00:00:00 is 1
The total defects for date 2015-12-11 00:00:00 is 1

答案 1 :(得分:1)

一个。你没有初始化计数。

B中。当您从defectdetailscopy中弹出元素时,您将减少defectdetailscopy的长度。因此,当您在if条件中将defectdetailscopy与defectdetails进行比较时,它会抛出索引超出范围的错误。也就是说,当j达到30时,defectdetailscopy中的元素数量为30.所以当你这样做时:

docker-compose logs

列表中没有第30个元素。它只是指数29。

更好的方法是使用字典。

我试过了:

defectdetails[i][0] == defectdetailscopy[30][0]

所以我得到以下结果:

将datetime格式化为字符串后:

date_wise_stats = {}
priority_list = {}
>>> for i in defectdetails:
...     if i[0] in date_wise_stats:
...             date_wise_stats[i[0]] += 1
...     else:
...             date_wise_stats[i[0]] = 1
...     if i[1] in priority_list:
...             priority_list[i[1]] += 1
...     else:
...             priority_list[i[1]] = 1   

答案 2 :(得分:0)

您可以使用列表推导或集合中的counter / defaultdict模块使其更小,但这是我认为的核心。

result = {}

# count it
for d in defectdetails:

    #init the a node for the day
    if d[0] not in result:
        result[d[0]] = {1:0,2:0,3:0}

    result[d[0]][d[1]] += 1

# report it
for d,defects in sorted(result.items()):
    print("%s, 1: %d, 2: %d, 3: %d, total: %d" % (
        d,
        defects[1],
        defects[2],
        defects[3],
        sum(n for n in defects.values()))
        )