这是一种两种编码风格的问题。我有一个tab-dl'd文件,其中'对象'由空行分隔。 '对象'的第一行是ID。直到空行的剩余行是属于对象的东西。我想将其解析为哈希,如下所示:
f = open(someFile, 'rb')
c = csv.reader(f, delimiter = "\t", quoting = csv.QUOTE_NONE)
thingstore = {}
try:
for row in c:
title = row[0]
thingstore[title] = set()
item = map(fixStupidExcelCrap, c.next())
while ''.join(item).strip() != '':
thingstore[title].add(tuple(item))
item = map(fixStupidExcelCrap, c.next())
except StopIteration:
pass
f.close()
我觉得有几件事情对这个解决方案很难看。首先,使用围绕整个函数的try块似乎要求问题,因为可能无法检测到格式不正确的文件。另一种方法是在try块中包装每个next()调用并设置一个标志以退出外部循环,这似乎也很糟糕。
其次,while ''.join(item).strip() != '':
非常难看。有没有更好的方法来测试由csv模块解析的空行?
更新
我错过了影响空行测试的细节。您可能已经猜到,代码正在解析从Excel导出的制表符分隔文件。在这种情况下,空行的有趣之处在于它们并非空白 - 文件中的所有行都有相同数量的标签。因此,如果excel文件中有3列,则为空导出的制表符分隔文件中的行将包含2个制表符,csv会将其解析为['', '', '']
bool
评估为True
的{{1}}。
因此,对于Ignacio更为漂亮的答案,for row in itertools.takewhile(bool, c):
将无法正常工作,因为它会扼杀文件的其余部分,包括空行和ID行。 for row in itertools.takewhile(lambda x: ''.join(x).strip() != '', c):
确实有效,但我们又回到了我想要避免的丑陋(条带()可能没有必要,但我把它放在安全的一边)。
答案 0 :(得分:3)
布莱什。空行会产生一个空列表。
with open(...) as fp:
c = csv.reader(fp)
while True:
try:
title = next(c)[0]
obj = set()
store[title] = obj
except StopIteration:
break
for row in itertools.takewhile(bool, c):
obj.add(tuple(row))