2012-07-25 104 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) 

转换成功,根据需要,我的输入文件包含的行数少于我的输出文件。