创建将仅为每行添加一个标题的csv

时间:2018-11-19 16:30:44

标签: python

我有一个看起来像这样的文件

a:1
a:2
a:3
b:1
b:2
b:2

,我希望它采用文件的a和b部分并将其添加为第一列和下面的数字,如下所示。

a b
1 1
2 2
3 3

可以做到吗?

1 个答案:

答案 0 :(得分:0)

CSV(逗号分隔文件)中应包含逗号,因此输出应包含逗号而不是空格分隔符。

我建议分两部分编写代码:第一部分应读取输入内容;第二部分应读取输入内容。第二个应该写出输出。

如果您输入的内容如下:

a:1
a:2
a:3
b:1
b:2
b:2
c:7

您可以像这样阅读输入内容:

#!/usr/bin/env python3
# Usage:  python3 scripy.py < input.txt > output.csv

import sys

# Loop through all the input lines and put the values in
# a list according to their category:
categoryList = {}  # key => category, value => list of values
for line in sys.stdin.readlines():
    line = line.rstrip('\n')
    category, value = line.split(':')
    if category not in categoryList:
        categoryList[category] = []
    categoryList[category].append(value)

# print(categoryList)  # debug line
# Debug line prints:  {'a': ['1', '2', '3'], 'b': ['1', '2', '2']}

这会将您的所有数据读入categoryList dict。这是一个字典,其中包含类别(字母)作为键,并包含列表(数字)作为值。将所有数据保存在该字典中后,就可以输出它了。

输出涉及获取类别列表(在您的示例情况下为字母),以便可以首先将其写为标题:

# Get the list of categories:
categories = sorted(categoryList.keys())
assert categories, 'No categories found!'  # sanity check

在这里,您可以使用Python的漂亮的 csv 模块输出标头,然后输出其余各行。在输出主数据时,我们可以使用外部循环遍历每个类别的 n 个条目,然后可以使用内部循环遍历每个类别:

import csv
csvWriter = csv.writer(sys.stdout)

# Output the categories as the CSV header:
csvWriter.writerow(categories)

# Now output the values we just gathered as
# Comma Separated Values:
i = 0  # the index into an individual category list
while True:
    values = []
    for category in categories:
        try:
            values.append(categoryList[category][i])
        except IndexError:
            values.append('')  # no value, so use an empty string
    if len(''.join(values)) == 0:
        break  # we've run out of categories that contain input
    csvWriter.writerow(values)
    i += 1  # increment index for the next time through the loop

如果您不想使用Python的 csv 模块,则仍需要弄清楚如何将类别中的条目分组在一起。而且,如果您只有简单的输出(其中所有条目都不包含引号,换行符或逗号),则可以手动写出输出。

您可以使用类似这样的方法来输出您的值:

# Output the categories as the CSV header:
print(','.join(categories))

# Now output the values we just gathered as
# Comma Separated Values:
i = 0  # the index into an individual category list
while True:
    values = []
    for category in categories:
        try:
            values.append(categoryList[category][i])
        except IndexError:
            values.append('')  # no value, so use an empty string
    if len(''.join(values)) == 0:
        break  # we've run out of categories that contain input
    print(','.join(values))
    i += 1  # increment index for the next time through the loop

这将打印出来:

a,b,c
1,1,7
2,2,
3,2,

通过遍历所有列表条目(外部循环),然后遍历所有类别(内部循环),然后打印出用逗号连接在一起的值,来完成此操作。

如果您不希望在输出中使用逗号,那么从技术上讲,您并不是在寻找CSV(逗号分隔值)输出。尽管如此,在那种情况下,修改代码以获取所需内容应该很容易。

但是,如果您有更复杂的输出(即其中包含引号,逗号和换行符的值),则应强烈考虑使用 csv 模块输出数据。否则,您将花费大量时间尝试使用 csv 模块已经处理的奇怪输入来修复模糊的错误。