这是两个编码风格问题合二为一。我有一个 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 块似乎是在询问问题,因为可能无法检测到格式不正确的文件。一种替代方法是将每个 next() 调用包装在 try 块中并设置一个标志以退出外部循环,这也看起来很 hacky。
其次,while ''.join(item).strip() != '':
非常难看。有没有更好的方法来测试由 csv 模块解析的空行?
更新:
我错过了一个影响空行测试的细节。您可能已经猜到了,该代码正在解析从 Excel 导出的制表符分隔文件。在这种情况下,空行的有趣之处在于它们并不是真正的空行——文件中的所有行都有相同数量的制表符。因此,如果您在 excel 文件中有 3 列,则导出的制表符分隔文件中的空行将包含 2 个制表符,csv 会将其['', '', '']
解析bool
为True
.
所以 wrt Ignacio 的更漂亮的答案是for row in itertools.takewhile(bool, c):
行不通的,因为它会占用文件的其余部分,包括空行和 ID 行。for row in itertools.takewhile(lambda x: ''.join(x).strip() != '', c):
确实有效,但我们又回到了我试图避免的丑陋(strip() 可能不是必需的,但为了安全起见,我把它放进去)。