【问题标题】:How do I add a list of dictionaries to another list of dictionaries?如何将字典列表添加到另一个字典列表?
【发布时间】:2011-10-24 11:40:23
【问题描述】:

我正在使用 for 循环将字典添加到字典列表(我称之为 data_file),使用 data_file.append()

它工作正常 :) 但后来我尝试在另一个 for 循环中向 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"

【问题讨论】:

  • 您是否收到错误消息?你能发布你的代码吗?
  • 嗨!我没有收到错误,它只是在我第二次要求它追加时没有添加任何内容。我已经添加了我的代码,抱歉,它看起来不是很好!
  • 在每个data_file.append(dictionary) 前添加一行print len(data_file), dictionary 并检查它是否正在打印您正在等待的数据。
  • 这并不能解决您的问题,但您知道吗if dictionary['AMOUNT'] not in ('Not Applicable', '0', '', '#N/A'):
  • 哦,谢谢 :) 我认为会有更好的方法来写,好吧 :)

标签: python list dictionary


【解决方案1】:

这是你的问题:

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

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

您的travel_generatorsmassage_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 文件名。如果这是您的意图,您可以通过在travel = filename 之后的行中添加break 来明确说明。

【讨论】:

  • 谢谢! :) 这解决了我的问题。抱歉,这是一个新手错误!
【解决方案2】:

在您提供的示例中,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)

【讨论】:

  • 非常感谢您的帮助 :) 关于解决方案的一个问题。我看到您正在对 csv.DictReader(open(travel)) 进行“映射”。我们不必定义地图的作用吗?第一个论点应该做什么?它是无。也许这会打开一大堆我不熟悉的东西。再次感谢!
  • map() 的第一个参数是一个函数,它应用于第二个参数中的每个项目,它必须是一个可迭代的。如果None,则假定恒等函数——也就是说,它不做任何操作。等同于open_file = [line for line in csv.DictReader(open(travel))]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 2016-09-14
  • 2013-09-28
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多