use*_*316 19 python csv string nonetype
我想None
在Python数据结构和使用Python csv
模块的csv表示之间来回时区分和清空字符串.
我的问题是,当我跑:
import csv, cStringIO
data = [['NULL/None value',None],
['empty string','']]
f = cStringIO.StringIO()
csv.writer(f).writerows(data)
f = cStringIO.StringIO(f.getvalue())
data2 = [e for e in csv.reader(f)]
print "input : ", data
print "output: ", data2
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
input : [['NULL/None value', None], ['empty string', '']]
output: [['NULL/None value', ''], ['empty string', '']]
Run Code Online (Sandbox Code Playgroud)
当然,我可以玩data
,并data2
区分None
和事情像空字符串:
data = [d if d!=None else 'None' for d in data]
data2 = [d if d!='None' else None for d in data2]
Run Code Online (Sandbox Code Playgroud)
但这部分会破坏我对csv
模块的兴趣(在C中实现的快速反序列化/序列化,特别是在处理大型列表时).
是否有一个csv.Dialect
或参数csv.writer
,并csv.reader
能够使他们之间的区别''
,并None
在此用例?
如果没有,是否有兴趣实施补丁csv.writer
来实现这种来回?(可能是一个Dialect.None_translate_to
参数默认''
为确保向后兼容)
mar*_*eau 12
您可以csv
通过创建自己的类似单例None
类/值的版本来至少部分地执行模块所做的操作:
class NONE(object):
def __repr__(self): # method csv.writer class uses to write values
return 'NONE' # unique string value to represent None
def __len__(self): # method called to determine length and truthiness
return 0 # (optional)
NONE = NONE() # singleton instance of the class
import csv
import cStringIO
data = [['None value', None], ['NONE value', NONE], ['empty string', '']]
f = cStringIO.StringIO()
csv.writer(f).writerows(data)
f = cStringIO.StringIO(f.getvalue())
print " input:", data
print "output:", [e for e in csv.reader(f)]
Run Code Online (Sandbox Code Playgroud)
结果:
input: [['None value', None], ['NONE value', NONE], ['empty string', '']]
output: [['None value', ''], ['NONE value', 'NONE'], ['empty string', '']]
Run Code Online (Sandbox Code Playgroud)
使用NONE
而不是None
保留足够的信息,以便能够区分它和任何实际的空字符串数据值.
即使是更好的选择......
你可以用同样的方法来实现对重量相对较轻的csv.reader
和csv.writer
"代理"类-必须的,因为你不能真正继承内置csv
这是写在C类-而不会引入大量的开销(因为大部分处理仍将由底层内置函数执行).这将使得完全透明,因为它全部封装在代理中.
import csv
class csvProxyBase(object): _NONE = '<None>' # unique value representing None
class csvWriter(csvProxyBase):
def __init__(self, csvfile, *args, **kwrags):
self.writer = csv.writer(csvfile, *args, **kwrags)
def writerow(self, row):
self.writer.writerow([self._NONE if val is None else val for val in row])
def writerows(self, rows):
map(self.writerow, rows)
class csvReader(csvProxyBase):
def __init__(self, csvfile, *args, **kwrags):
self.reader = csv.reader(csvfile, *args, **kwrags)
def __iter__(self):
return self
def next(self):
return [None if val == self._NONE else val for val in self.reader.next()]
if __name__ == '__main__':
import cStringIO as StringIO
data = [['None value', None], ['empty string', '']]
f = StringIO.StringIO()
csvWriter(f).writerows(data)
f = StringIO.StringIO(f.getvalue())
print " input:", data
print "output:", [e for e in csvReader(f)]
Run Code Online (Sandbox Code Playgroud)
结果:
input: [['None value', None], ['empty string', '']]
output: [['None value', None], ['empty string', '']]
Run Code Online (Sandbox Code Playgroud)
Bre*_*arn 11
文档表明你想要的是不可能的:
为了使与实现DB API的模块接口尽可能简单,将值None写为空字符串.
这是在writer
该类的文档中,表明它适用于所有方言,并且是csv模块的固有限制.
我支持改变这个(以及csv模块的各种其他限制),但可能是人们想要将这种工作卸载到不同的库中,并保持CSV模块简单(或者至少简单因为它是).
如果您需要更强大的文件读取功能,您可能需要查看numpy,scipy和pandas中的CSV读取功能,我记得有更多选项.
归档时间: |
|
查看次数: |
24306 次 |
最近记录: |