2012-07-25 67 views
0

我有一個dict,它描述了我想要應用於CSV文件中每一行的映射。Python CSV:根據字典映射寫入行

dict1 = {"key1":["value1", "value2"], "key2":["value3"]} 

我的程序應該讀一行和映射特定列由dict提供的值(一個或多個)的關鍵。如果每個鍵只有一個值,那麼腳本應將包含新值的行寫入新文件。如果某個鍵有多個值,則應爲每個值寫入一個新行。例如,csvin包含2行。一行有一列,其中key1存在,另一列有key2。在這種情況下,輸出文件csvout應包含行比csvin,實際上3.行中的兩個(與key1相關聯)將除了一個單一值相同

我現在的劇本是這樣的:

def convSan(sfin, cfout): 
    with open(sfin, "rb") as fin: 
     with open(cfout, "wb") as fout: 
      csvin = csv.reader(fin) 
      csvout = csv.writer(fout, delimiter=",") 
      fline = csvin.next() 
      csvout.writerow(fline) 

     for row in csvin: 
      row[25] = dict1[row[25]] 
      csvout.writerow(row) 

這將產生相同數量的輸入文件列的輸出文件,但填充各個領域與正確的新值(現在有些字段值列表)。

@ sr2222提供的答案適用於簡單列表的情況,但無法在我的特定情況下使用。

幫助表示讚賞。

+2

您是否嘗試過使用'dict's?它們非常適合描述映射。 – Kevin 2012-07-25 19:54:32

+0

你想用什麼取代什麼?你的第一個循環就是將所有的list1切換到等於list2的元素。 – 2012-07-25 19:55:05

回答

1

第一:

for index, value in enumerate(list1): 
    list1[index] = list2[index] 

是格式化你的第一個環一個更清潔的方式。但是,這相當於list1 = copy.copy(list2)。我認爲你正在試圖做的是:

normalized_values = ['123', '456'] 
content = ['a123', '123', 'b456', '789'] 
for index, value in enumerate(content): 
    for normalized_value in normalized_values: 
     if normalized_value in value: 
      content[index] = normalized_value 

這將留給你:問題更新後

content = ['123', '123', '456', '789'] 

編輯:

replacement_map = {'123' : ('a123', '1234'), '456' : ('00456',)} 
input = ['123', '456', '234', '123', '789'] 
output = [] 
for value in input: 
    try: 
     output.extend(replacement_map[value]) 
    except KeyError: 
     output.append(value) 

在try /除了等同於:

if value in replacement_map: 
    output.extend(replacement_map[value]) 
else: 
    output.append(value) 

作爲迴應建設從2只列出了地圖上述評論(請注意,這隻會行爲正確,如果你能總是假設列表1和列表2的長度相同):

replacement_map = {} 
for key, value in zip(list1, list2): 
    try: 
     replacement_map[key].append(value) 
    except KeyError: 
     replacement_map[key] = [value] 
+0

您能否將您的問題更新爲您預期輸出的問題,以確定您認爲有問題的輸入? (在第二個代碼塊中的2個列表) – 2012-07-25 20:15:29

+0

可以接受這個問題的答案,然後... :) – 2012-07-25 22:16:24

+0

我接受了這個anser,因爲我不能沒有你的幫助。謝謝。 – CHM 2012-07-26 01:32:16

0

對於有興趣,我可以使它工作像這樣:

def convSan(sfin, cfout): 
    with open(sfin, "rb") as fin: 
     with open(cfout, "wb") as fout: 
      csvin = csv.reader(fin) 
      csvout = csv.writer(fout, delimiter=",") 
      fline = csvin.next() 
      csvout.writerow(fline) 
      buff = [] 

      for row in csvin: 
       dl = ce.dict1200[row[25]] 
       if len(dl) == 1: 
        row[25] = dl[0] 
        csvout.writerow(row) 
       else: 
        for i in range(len(dl)-1): 
         row[25] = dl[i] 
         csvout.writerow(row) 

轉換成功,根據需要,我的輸入文件包含的行數少於我的輸出文件。