【问题标题】:Parse non-homogeneous CSV file with Python使用 Python 解析非同质 CSV 文件
【发布时间】:2016-10-26 04:03:21
【问题描述】:

我有一个结构如下的 CSV 文件:

# Samples 1
1,58
2,995
3,585

# Samples 2
15,87
16,952
17,256

# Samples 1
4,89
5,63
6,27

在 Python 3.x 中有什么方法,如何解析这样结构的文件而无需手动逐行遍历?

我想要一些函数,它会根据标签自动解析它,如下所示:

>> parseLabeledCSV(['# Samples 1', '# Samples 2'], fileName)
[{1:58,2:995,3:585,4:89,5:63,6:27}, {15:57, 16:952, 17:256}]

【问题讨论】:

  • 你是什么意思parse,分成几列?有许多专门用于读取csv数据的python包。
  • 非同质是什么意思?这些行对我来说看起来是同质的:每行都有两个整数。请用预期的输出更新您的帖子。您是否查看过 csv 库模块?
  • 编辑显着改变了问题的含义。最初完全不清楚这些是键值对。
  • @Kupiakos 对不起,我希望现在更清楚了。
  • @Eenoku 考虑到这似乎是一种自定义格式,我想说最安全的选择是逐行进行。

标签: python python-3.x csv parsing


【解决方案1】:

groupby 将为您完成所有迭代和分组。在这种情况下,您只关心那些包含 ',' 的连续行组(或仅由 ',' 和数字组成,或您想定义的任何其他过滤谓词):

input="""# Samples 1
1,58
2,995
3,585

# Samples 2
15,87
16,952
17,256

# Samples 1
4,89
5,63
6,27""".splitlines()

from itertools import groupby
import csv

results = []
for has_comma, data_lines in groupby(input, key=lambda s: ',' in s):
    if has_comma:
        results.append(dict(csv.reader(data_lines)))

这甚至可以折叠成一个 Python 列表理解语句:

results = [dict(csv.reader(data_lines)) 
            for has_comma, data_lines in groupby(input, key=lambda s: ',' in s) 
                if has_comma]

在这两种情况下,使用以下命令打印结果:

for dd in results:
    print(dd)

得到:

{'1': '58', '3': '585', '2': '995'}
{'15': '87', '17': '256', '16': '952'}
{'5': '63', '4': '89', '6': '27'}

【讨论】:

    【解决方案2】:

    这样的?

    input="""# Samples 1
    1,58
    2,995
    3,585
    
    # Samples 2
    15,87
    16,952
    17,256
    
    # Samples 1
    4,89
    5,63
    6,27"""
    
    
    def parse(input):
        parsed = {}
        lines = input.split("\n")
        key = "# Unknown"
        for line in lines:
            if line is None or line == "": #  ignore empty line
                continue
            if line.startswith("#") :
                if not parsed.has_key(line):
                    parsed[line] = {}
                key = line
                continue
            left, right = line.split(",")
            parsed[key][left] = right
        return parsed
    
    
    if __name__ == '__main__':
        output = parse(input)
        print(output)
    

    将输出到:

    {'# Samples 1': {'1': '58', '3': '585', '2': '995', '5': '63', '4': '89', '6': '27'}, '# Samples 2': {'15': '87', '17': '256', '16': '952'}}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-07
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      相关资源
      最近更新 更多