我有一个包含以下信息的csv文件:
id name age height weight
1 x 12 11 124
2 y 13 23 432
3 z 14 43 1435
它存储在名为Workbook2.csv的文件中 我使用以下代码:
ipFile = csv.DictReader(open('Workbook2.csv', 'rU'))
dict = {} # Tring to update the rows to this dictionary.
for row in ipFile:
print row
我得到以下结果:
{'weight': '124', '\xef\xbb\xbfid': '1', 'height ': '11', 'age ': '12', 'name ': 'x'}
{'weight': '432', '\xef\xbb\xbfid': '2', 'height ': '23', 'age ': '13', 'name ': 'y'}
{'weight': '1435', '\xef\xbb\xbfid': '3', 'height ': '43', 'age ': '14', 'name ': 'z'}
我想知道如何将此输出更新为字典。 我还想知道我如何忽略使用UTF-8编码的unicode字符,如果有一个过滤器我可以用来消除它们。
答案 0 :(得分:2)
您的输入数据在每一行上都包含UTF-8 BOM sequences。无论是什么产生这个文件,似乎都是使用natsort()
编解码器或非Python等价物一次一行追加数据。 BOM(如果使用的话)应该是文件中的第一个字符,而不在其他地方使用。如果你可以在源头解决这个问题,那么你的数据就会被破坏。
但是,有一种方法可以在阅读时修复此问题。 utf-8-sig
模块读取的“文件”可以是在迭代时生成行的任何内容。使用生成器首先过滤文件行:
csv
然后将文件传递给过滤器,然后将其传递给from codecs import BOM_UTF8
def bom_filter(lines):
for line in lines:
if line.startswith(BOM_UTF8):
line = line[len(BOM_UTF8):]
yield line
对象:
DictReader()
演示:
with open('Workbook2.csv', 'rU') as inputfile:
ipFile = csv.DictReader(bom_filter(inputfile))
在Python 3中,>>> from io import BytesIO
>>> import csv
>>> from codecs import BOM_UTF8
>>> def bom_filter(lines):
... for line in lines:
... if line.startswith(BOM_UTF8):
... line = line[len(BOM_UTF8):]
... yield line
...
>>> demofile = BytesIO('''\
... \xef\xbb\xbfid,name,age,height,weight
... \xef\xbb\xbf1,x,12,11,124
... \xef\xbb\xbf2,y,13,23,432
... \xef\xbb\xbf3,z,14,43,1435
... ''')
>>> ipFile = csv.DictReader(bom_filter(demofile))
>>> for row in ipFile:
... print row
...
{'age': '12', 'height': '11', 'id': '1', 'weight': '124', 'name': 'x'}
{'age': '13', 'height': '23', 'id': '2', 'weight': '432', 'name': 'y'}
{'age': '14', 'height': '43', 'id': '3', 'weight': '1435', 'name': 'z'}
模块采用Unicode字符串输入(而不是字节串,所以现在需要查找解码结果,U + FEFF零宽度空间代码点。使代码工作在任何一个Python版本中,你必须在行的开头换掉你正在测试的内容:
csv
答案 1 :(得分:1)
有一个kwarg skipinitialspace但我从C代码验证它只查找''。
两种可能性:
(2)的一个例子是:
def self.search(query)
where(['phone ilike :query',
'LOWER(name) ilike :query',
'LOWER(email) ilike :query',
'LOWER(address) ilike :query'].join(' OR '), {query: "%#{query}%" })
end
答案 2 :(得分:0)
我认为输出明显被误解了。
DictReader从第一行获取字段名,第一列(在不可见BOM之后的那一列)只是“id”。这就是id字段现在每个记录都有前缀的原因。
在python 2.7和3.6中,我不得不使用方言csv.excel_tab
来将标签解释为分隔符。
您的输入数据/ csv文件绝对可以,因为开头只有一个BOM(它应该在哪里)。您只需要在阅读之前剥离BOM。
E.g。像这样:
from codecs import BOM_UTF8
csv_file = open('test2.csv', 'rU')
csv_file.seek(len(BOM_UTF8))
ipFile = csv.DictReader(csv_file, dialect=csv.excel_tab)