在Python中重新格式化从CSV文件读取的列表中的项目

时间:2009-12-08 03:41:00

标签: python parsing csv replace delimiter

我在CSV文件中有一些这样的行:

1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2

如果你注意到,有些数字用“”括起来,并且有一千个分隔符“,”。我想删除千位分隔符和双引号机箱。对于qoute外壳,我正在考虑使用string.replace()但是引号内的逗号怎么样?

在Python中执行此操作的最佳方式是什么?

6 个答案:

答案 0 :(得分:2)

您可以简单地解析CSV,进行必要的更改,然后再次写入。

(我没有测试过这段代码,但它应该是这样的)

import csv
reader = csv.reader(open('IN.csv', 'r'))
writer = csv.writer(open('OUT.csv', 'w')
for row in reader:
 # do stuff to the row here
 # row is just a list of items
 writer.writerow(row)

答案 1 :(得分:2)

这里有一些正则表达式,可以解决这个问题:

>>> import re
>>> p = re.compile('["]([^"]*)["]')
>>> x = """1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2"""
>>> p.sub(lambda m: m.groups()[0].replace(',',''), x)
'1000001234,Account Name,0,0,3711.32,0,0,18629.64,22340.96,COD,20000.00,Some string,Some string 2'

从引号对之间的字符串部分中删除逗号。

答案 2 :(得分:1)

如果您只想从字符串中删除双引号和逗号,则可以执行以下几项替换:

s = s.replace('"','').replace(',','')

更快捷的方法是使用s.translate,但这需要最少的准备工作:

import string
identity = string.maketrans('', '')

...

s = s.translate(identity, '",')

这会删除任何双引号或逗号,并且也会很快。通常,字符串对象的.translate方法是从字符串中删除某些字符的最佳方法(以及可能执行某些字符到字符的转换,但是,通过使用转换表,例如我在这里展示的identity,翻译部分实际上可以轻易绕过)。请注意.translate对于Unicode对象(因此也适用于Python 3字符串)的工作方式略有不同 - 我给出的方法适用于纯Python 2字符串对象。

答案 3 :(得分:1)

这是我刚刚测试的东西,你可能不需要pprint,我只想用于清晰的输出。

test.csv

1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2
1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2

代码,使用csv reader,并将每个项目传递给parseNum函数以检查有效数字。

from pprint import pprint
import csv

def parseNum(x):
    xx=x.replace(",","")
    if not xx.replace(".","").isdigit(): return x
    return "." in xx and float(xx) or int(xx)

x=[map(parseNum,line) for line in csv.reader(open("test.csv"))]

pprint(x)

输出

[[1000001234,
  'Account Name',
  0,
  0,
  3711.3200000000002,
  0,
  0,
  18629.639999999999,
  22340.959999999999,
  'COD',
  20000.0,
  'Some string',
  'Some string 2'],
 [1000001234,
  'Account Name',
  0,
  0,
  3711.3200000000002,
  0,
  0,
  18629.639999999999,
  22340.959999999999,
  'COD',
  20000.0,
  'Some string',
  'Some string 2']]

注意:如果浮点数需要很好的精度,请将 float 替换为Decimal

答案 4 :(得分:1)

使用csv模块。它具有各种常量和参数,可帮助您为您正在使用的文件类型设置分隔符,引号和其他所有内容。它甚至还有一个Sniffer,可以帮助您识别文件的csv格式。事实上,这是我发现的唯一可以正确使用csv文件的模块。

http://docs.python.org/library/csv.html

答案 5 :(得分:1)

您绝对应该使用csv模块。如果你使用csv.reader,你只会遇到一个非常小的问题:测试字段以查看它们是否为数字,如果是,则删除逗号。我把它打包成发电机:

import csv

def read_and_fix_numbers(f):
    """Iterate over a file object that returns CSV data, stripping commas out of numbers."""
    for row in csv.reader(f):
        for field in row:
            try:
                x = float(field)
                field.replace(",", "")
            except ValueError:
                pass
            fixed.append(field)
        yield fixed

用法:

>>> data = '1000001234,Account Name,0,0,"3,711.32",0,0,"18,629.64","22,340.96",COD,"20,000.00",Some string,Some string 2'
>>> import StringIO
>>> f = StringIO.StringIO(data)
>>> for row in read_and_fix_numbers(f):
        print row
['1000001234', 'Account Name', '0', '0', '3711.32', '0', '0', '18629.64', '22340.96', 'COD', '20000.00', 'Some string', 'Some string 2']