Как добавить список словарей в другой список словарей? - PullRequest
1 голос
/ 24 октября 2011

Я использую цикл for для добавления словаря в список словарей (который я называю data_file), используя data_file.append ()

Работает нормально :) Но потом я пытаюсь добавить еще несколько словарей в data_file в другой цикл for, и я снова использую 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"

Ответы [ 2 ]

1 голос
/ 24 октября 2011

Вот ваша проблема:

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

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

Ваши списки travel_generators и massage_generators используют один и тот же открытый файл для перебора и получения данных; проблема в том, что как только файл был повторен один раз csv.DictReader в massage_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)):

Кроме того, в вашем первом цикле, где вы собираете имена файлов: имейте в виду, что цикл сохраняет только имя файла last , которое соответствует. Если это ваше намерение, вы можете сделать это, добавив break в строке после travel = filename.

0 голосов
/ 24 октября 2011

В приведенном вами примере generators, travel_generators и massage_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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...