2011-10-24 136 views
1

我正在使用for循環來添加字典到字典列表(我打電話data_file),使用data_file.append()如何將詞典列表添加到另一個詞典列表?

它工作正常:)但後來我嘗試添加一些更多的字典data_file在另一個循環,我再次使用data_file.append(),它不起作用。它不會將這些字典添加到data_file

有誰知道我在做什麼錯?

我沒有收到錯誤。它只產生一個只有來自massage_generators的字典的文件。它不包含travel_generators中的任何內容。

我甚至試過註釋掉第一個for循環,第一個用於massage_generators,在那種情況下,它添加在travel_generators字典中。這就像我不能使用.append()兩次?

任何幫助將不勝感激請!

對不起,它不是很優雅,我只是在學習這個編碼的東西! :)

感謝

import csv 
import copy 
import os 
import sys 


generators = list() 

for filename in os.listdir(os.getcwd()): 
    root, ext = os.path.splitext(filename) 
    if root.startswith('Travel Allowance Auto Look up') and ext == '.csv': 
     travel = filename 

open_file = csv.DictReader(open(travel)) 
generators.append(open_file)  

travel_generators = generators[:] 
massage_generators = generators[:] 

data_file = [] # result will be stored here (List of dicts) 


travel_remap = {'FINAL_TRAVEL_ALL':'AMOUNT'} 
massage_remap = {'MASSAGE_BIK':'AMOUNT'} 


for generator in massage_generators: 
    for dictionary in generator: 
    dictionary['PAYMENT_TYPE_CODE'] = 'MASSAGE_BIK' 
    dictionary['COMMENT'] = 'Massage BIK' 
    dictionary['IS_GROSS'] = 'FALSE' 
    dictionary['PAYMENT_TO_DATE'] = '01/01/2099' 
    dictionary['PAID MANUALLY'] = 'FALSE' 
    for old_key, new_key in massage_remap.iteritems(): 
     if old_key not in dictionary: 
     continue 
     dictionary['AMOUNT'] = dictionary['MASSAGE_BIK'] 
     del dictionary['MASSAGE_BIK'] 
     if (dictionary['AMOUNT'] != '0' and dictionary['AMOUNT'] != ''): 
      data_file.append(dictionary) 

for generator in travel_generators: 
    for dictionary in generator: 
    dictionary['PAYMENT_TYPE_CODE'] = 'TRANSPORTATION_ALLOWANCE' 
    dictionary['COMMENT'] = 'Annual travel allowance paid in monthly installments' 
    dictionary['IS_GROSS'] = 'TRUE' 
    dictionary['PAYMENT_TO_DATE'] = '01/01/2099' 
    dictionary['PAID MANUALLY'] = 'FALSE' 
    for old_key, new_key in travel_remap.iteritems(): 
     if old_key not in dictionary: 
     continue 
     dictionary['AMOUNT'] = dictionary['FINAL_TRAVEL_ALL'] 
     del dictionary['FINAL_TRAVEL_ALL'] 
     if (dictionary['AMOUNT'] != 'Not Applicable' and dictionary['AMOUNT'] != '0' and dictionary['AMOUNT'] != '' and dictionary['AMOUNT'] != '#N/A'): 
      data_file.append(dictionary) 


keys = ['EMPID', 'Common Name', 'PAYMENT_TYPE_CODE', 'CURRENCY', 'AMOUNT', 'EFFECTIVE_DATE', 
     'COMMENT', 'PAYMENT_FROM_DATE', 'PAYMENT_TO_DATE', 'IS_GROSS', 'HIDDEN_UNTIL', 'PAID MANUALLY', 'PAYMENT_DATE'] 

bulk_upload = open('EMEA Bulk Upload.csv', 'wb') 
dict_writer = csv.DictWriter(bulk_upload, keys, restval='', extrasaction='ignore') 
dict_writer.writer.writerow(keys) 
dict_writer.writerows(data_file) 

print "Everything saved! Look up EMEA Bulk Upload.csv" 
+8

您是否收到錯誤消息?你能發佈你的代碼嗎? – thegrinner

+0

嗨!我沒有收到任何錯誤,只是第二次添加任何內容而沒有添加任何內容。我已經添加了我的代碼,對不起,這不是很好看! –

+1

在每個'data_file.append(dictionary)'之前用'print len(data_file),dictionary'添加一行並檢查它是否正在打印您正在等待的數據。 – eumiro

回答

1

這是你的問題:

open_file = csv.DictReader(open(travel)) 
generators.append(open_file)  

travel_generators = generators[:] 
massage_generators = generators[:] 

travel_generatorsmassage_generators名單都使用相同的打開文件遍歷和獲取數據;那個問題就是一旦文件被csv.DictReadermassage_generators中被迭代一次,它已經被用盡,並且當你嘗試在travel_generators中再次讀取它時沒有更多的數據。

試試這個:

generators.append(travel)  # just the filename  

travel_generators = generators[:] 
massage_generators = generators[:] 

,然後在你的循環:

for filename in massage_generators: 
    for dictionary in csv.DictReader(open(filename)): 

而且,你在哪裏收集文件名的第一個循環:注意循環只保存最後匹配的文件名。如果這是你的意圖,你可以通過在travel = filename之後在線上添加break來清除它。

+0

謝謝! :)這解決了我的問題。對不起,什麼菜鳥錯誤! –

0

在您提供的示例中,generatorstravel_generatorsmassage_generators都完全相同,並且每個都包含相同的open_file實例。當您迭代massage_generators時,您會到達文件的末尾。然後當迭代travel_generators時,在open_file中沒有什麼可以迭代的了。

最起碼,你可以更改以下行:

open_file = csv.DictReader(open(travel)) 

要:現在

open_file = map(None, csv.DictReader(open(travel))) 

open_file是一個列表,而不是一臺發電機,並可以重複和再重複。

但是,我建議您迭代一次文件,然後構建兩個字典,並在每次迭代中寫入一個DictWriter實例。

open_file = csv.DictReader(open(travel)) 
... 
dict_writer = csv.DictWriter(bulk_upload, keys, restval='', extrasaction='ignore') 
dict_writer.writer.writerow(keys) 

for line in open_file: 
    massage_dictionary={} 
    massage_dictionary.update(line) 
    ... # manipulate massage_dictionary 
    dict_writer.writerow(massage_dictionary) 

    travel_dictionary={} 
    travel_dictionary.update(line) 
    ... # manipulate travel_dictionary 
    dict_writer.writerow(travel_dictionary) 
+0

非常感謝您的幫助:)關於解決方案的一個問題。我看到你在做'映射'到csv.DictReader(打開(旅行))。我們不需要定義什麼地圖呢?第一個理由是什麼?它在None中。也許這是開放了一大堆我不熟悉的東西。再次感謝! –

+0

map()的第一個參數是一個函數,它被應用於第二個參數中的每個項目,它必須是一個可迭代的。如果「無」,則假定身份函數 - 也就是說,它不做任何操縱。它與'open_file = [line for csv.DictReader(open(travel))]''一致 –