0

我有一个dict描述我想应用于 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 提供的答案适用于简单列表,但我无法让它在我的特定情况下工作。

帮助表示赞赏。

4

2 回答 2

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/except 相当于:

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

作为对上述从 2 个列表构建地图的评论的回应(请注意,只有当您始终可以假设 list1 和 list2 的长度相同时,这才会正确运行):

replacement_map = {}
for key, value in zip(list1, list2):
    try:
        replacement_map[key].append(value)
    except KeyError:
        replacement_map[key] = [value]
于 2012-07-25T20:06:45.233 回答
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)

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

于 2012-07-26T01:31:06.487 回答