2017-05-30 48 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