【问题标题】:How to read in a file with a mixture of different delimiters using Python csv module?如何使用 Python csv 模块读取混合了不同分隔符的文件?
【发布时间】:2014-10-15 18:51:15
【问题描述】:

输入:

A    B    C
D    E    F

这个文件不是完全用制表符分隔的,有些条目是用空格分隔的,看起来像是用制表符分隔的(这很烦人)。我尝试使用规范的制表符分隔选项使用csv 模块读取文件,希望它不会介意几个空格(不用说,我的输出被这段代码搞砸了):

with open('file.txt') as f:
    input = csv.reader(f, delimiter='\t')
    for row in input:
        print row

然后我尝试用csv.reader('\t'.join(f.split())) 替换第二行以尝试利用Remove whitespace in Python using string.whitespace,但我的错误是:AttributeError: 'file' object has no attribute 'split'

我也尝试检查Can I import a CSV file and automatically infer the delimiter?,但这里的 OP 导入了分号分隔或逗号分隔的文件,但没有导入两种分隔符的随机混合文件。

想知道csv 模块是否可以处理混合各种分隔符的文件读取,或者我是否应该尝试不同的方法(例如,不使用csv 模块)?

我希望有一种方法可以读取混合分隔符的文件并自动将此文件转换为制表符分隔的文件。

【问题讨论】:

  • 你的空格分隔线是否总是用相同数量的空格分隔?
  • 我会说最好规范化你的文件然后处理它,而不是整天处理边缘情况。
  • 我同意,但是如果文件有数百行长,我将如何对其进行规范化/处理?也许csv 模块有更好的替代方案?
  • 任何有引号的字段:"A Dont break B"?
  • @dawg:文件字段中没有引号。

标签: python csv


【解决方案1】:

只需使用 .split():

csv='''\
A\tB\tC
D    E    F
'''

data=[]
for line in csv.splitlines():
    data.append(line.split())

print data 
# [['A', 'B', 'C'], ['D', 'E', 'F']]

或者,更简洁:

>>> [line.split() for line in csv.splitlines()]  
[['A', 'B', 'C'], ['D', 'E', 'F']]

对于一个文件,类似:

with open(fn, 'r') as fin:
    data=[line.split() for line in fin]

之所以有效,是因为str.split() 会在数据元素之间的所有空白处拆分,即使有超过 1 个空白字符或混合使用:

>>> '1\t\t\t2     3\t  \t  \t4'.split()
['1', '2', '3', '4']

【讨论】:

  • +1 并接受了答案,用于展示如何使用 .split() 完成您希望 csv 模块可以轻松完成的工作。
  • 如果值中有空格(例如用引号字符分隔的字符串),此方法将失败。
【解决方案2】:

为什么不直接使用您自己的拆分器而不是 CSV 模块?

delimeters = [',', ' ', '\t']

unique = '[**This is a unique delimeter**]'

with open(fileName) as f:
    for l in f: 
        for d in delimeters: l = unique.join(l.split(d))
        row = l.split(unique)

【讨论】:

    【解决方案3】:

    .split() 对于“连续、任意混合制表符和空格作为一个分隔符”的情况是一种简单而好的解决方案;但是,当出现带有空白(用引号括起来)的值时,这不起作用。

    首先,我们可以将文本文件中的每个选项卡替换为一个空白' ';这可以将情况简化为“连续的、任意数量的空白作为一个分隔符”。
    有一个很好的例子来替换文件中的模式: https://www.safaribooksonline.com/library/view/python-cookbook/0596001673/ch04s04.html
    注意 1: 请勿替换为 ''(空字符串),因为分隔符可能仅包含制表符。
    注意 2: 当您在用引号括起来的值中包含制表符 (/t) 时,此方法不起作用。

    然后我们可以使用Python的csv模块,分隔符为' '(一个空格),使用skipinitialspace=True忽略连续的空格。

    【讨论】:

      猜你喜欢
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-27
      • 2017-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多