2017-05-30 60 views
-1

具体文字及字符有像这样的列表(只有这样,更大)被称为“DATA_LIST”:去除字典

2017-04-01, available 
2017-04-02, available 
2017-04-01, available 
2017-04-02, available 
2017-04-02, available 
2017-04-01, available 
2017-04-02, available 
2017-04-01, available 
2017-04-02, available 
2017-04-01, available 
etcetera 

我用下面的代码,

dates = collections.defaultdict(list) 
for date, xyz in data_list: 
    dates[date].append(xyz) 
counts = {date: collections.Counter(xyz) for date, xyz in dates.items()} 

要创建像一本字典这个:

2017-04-01,Counter({'available': 9}) 
2017-04-02,Counter({'available': 12}) 
2017-04-03,Counter({'available': 9}) 
2017-04-04,Counter({'available': 4}) 
2017-04-05,Counter({'available': 9}) 
2017-04-06,Counter({'available': 2}) 

我将如何继续删除“计数器”? (最终像“(”和“{”字符)

目前,我有这样的代码,但它不会做任何事情。

for x in my_dictionary: 
try: 
    x = x.replace('Counter','') 
except: 
    pass 

主要目标最终是让.csv文件像这样:

date, available 
2017-04-01, 9 
2017-04-02, 12 
2017-04-03, 9 
2017-04-04, 4 
2017-04-05, 9 
2017-04-06, 2 

字典的打印输出部分:

'2018-12-12': Counter({'available': 3}), '2018-04-28': Counter({'available': 4}), '2017-12-16': Counter({'available': 2}), '2017-12-17': Counter({'available': 2}), '2017-12-14': Counter({'available': 2}), '2017-12-15': Counter({'available': 2}), '2017-12-12': Counter({'available': 2}), '2017-12-13': Counter({'available': 2}), '2017-12-10': Counter({'available': 2}), '2017-12-11': Counter({'available': 2}), '2017-12-18': Counter({'available': 2}), '2017-12-19': Counter({'available': 2}), '2018-05-31': Counter({'available': 4}), '2018-05-30': Counter({'available': 4}), 
+0

你希望输出不是一个列表。还有那些'Counters'是'collections.Counter'对象(不是字符串),你可以简单地访问键和值,如果你想。 – Kasramvd

+0

它曾经是一个字典,我将它转换为一个列表,其中列出了“for count.items():listcalender.append(x)”中的x。 where“counts”是orignal字典。所以你说最好保留字典并删除那里的角色? – David

+0

是的,如果你能从字典中获得更好的方式。即使你的项目仍然是复杂的对象,你可以解析它们,让你期望的项目在嵌套循环,或整个操作在列表理解。 – Kasramvd

回答

0

就快可以得到AV通过使用available键ailable数从柜台得到的,就像这样:

counts = {date: collections.Counter(xyz)['available'] for date, xyz in dates.items()} 


import csv 

def to_row(date, counter): 
    return date, counter['booked'], counter['blocked'], counter['available'] 

counts = [to_row(date, collections.Counter(xyz)) for date, xyz in dates.items()] 

writer = csv.writer(open('<filename>.csv', 'w')) 
writer.writerows(counts) 
+0

确实有这个技巧。我将如何适应这段代码,以便我可以采取3个状态?像预订,封锁和可用。 – David

+0

你想如何退货?作为状态的日期和元组的字典? –

+0

看到你想要它作为CSV,返回列表清单似乎要走的路。 '[[日期,预订,封锁,可用],...]'。然后,您可以使用CSVWriter中的'writerows'来编写列表。 –

1

你不需要在这种情况下collections.Counter可言的,你甚至可以用collections.defaultdict做了。这将做伎俩:

dates = {} 
for date, value in data_list: 
    if value == "available": 
     dates[date] = dates.get(date, 0) + 1 
# dates contains (date, count) pairs 

而且应该也快得多。然后你可以使用csv.writercsv.DictWriter(取决于你想要的输出CSV)写出你的最终CSV。例如:

import csv 

data_list = [['2017-04-01', 'available'], 
      ['2017-04-02', 'available'], 
      ['2017-04-01', 'available'], 
      ['2017-04-02', 'available'], 
      ['2017-04-02', 'available'], 
      ['2017-04-01', 'available'], 
      ['2017-04-02', 'available'], 
      ['2017-04-01', 'available'], 
      ['2017-04-02', 'available'], 
      ['2017-04-01', 'available']] 

dates = {} 
for date, value in data_list: 
    if value == "available": 
     dates[date] = dates.get(date, 0) + 1 

with open("output.csv", "wb") as f: # open output.csv for writing 
    writer = csv.writer(f) # create a csv.writer 
    writer.writerow(("date", "available")) # write our header 
    for row in dates.iteritems(): # sorted(dates.iteritems()) instead for date-sorted output 
     writer.writerow(row) # write the row 

让你有效的CSV为:

date,available 
2017-04-02,5 
2017-04-01,5 

,您可以在几乎任何电子表格应用程序打开它。如果您想将其格式化为您的输出,请注意这不是有效的CSV。

UPDATE - 一个版本有多个可用值对于每一日期(在使用collections.Counter变得更方便了这一点,但为了保持与主题):

import csv 

data_list = [['2017-04-01', 'available'], 
      ['2017-04-02', 'available'], 
      ['2017-04-01', 'booked'], 
      ['2017-04-02', 'available'], 
      ['2017-04-02', 'booked'], 
      ['2017-04-01', 'available'], 
      ['2017-04-02', 'blocked'], 
      ['2017-04-01', 'blocked'], 
      ['2017-04-02', 'blocked'], 
      ['2017-04-01', 'available']] 

dates = {} 
values = set() # just so we know what are possible values for the latter CSV header 
for date, value in data_list: 
    values.add(value) 
    dates.setdefault(date, {})[value] = dates.get(date, {}).get(value, 0) + 1 

with open("output.csv", "wb") as f: # open output.csv for writing 
    header = ["date"] + list(values) # set header to date,<available_values> 
    writer = csv.DictWriter(f, header) 
    writer.writeheader() 
    for k, v in dates.iteritems(): # sorted(dates.iteritems()) instead for date-sorted output 
     v.update({"date": k}) # add the date to our row 
     writer.writerow(v) # write the row 

创建output.csv为:

date,available,booked,blocked 
2017-04-02,2,1,2 
2017-04-01,3,1,1 

您可以拥有任意数量的“价值”字段,因此它不必仅为3。

+0

如果有3个可能的状态,这也可以工作吗?例如预订和屏蔽?因此,在每个日期之后,可以有3个数字:已预订,已封锁和可用的数量。 – David

+0

是的,如果你只对'available'状态感兴趣。如果你需要所有三个状态集合.Counter'可能会更方便一些(并且更易于维护),但是你可以用'dates.setdefault(date,{})[value] = dates.get日期,{})。get(value,0)+ 1'而不是检查“value ==”是否可用“并仅计算可用条目 - 这会给你一个所有计数作为输出的词典。写入CSV时,您需要使用'csv.DictWriter'(或手动计算位置)。 – zwer

+0

您需要在代码中放置dates.setdefault(date,{})[value] = dates.get(date,{})。get(value,0)+ 1以使其工作?我对python相当陌生。抱歉。 – David