嵌套循环,迭代器和csv
其中一种是两种编码风格的问题。 我有一个tab-dl'd文件,其中“对象”由空行分隔。 “对象”的第一行是ID。 直到空行的剩余行是属于该对象的东西。 我想parsing这个哈希如下:
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()
对于这个解决scheme,我认为有几件事情是丑陋的。 首先,围绕整个函数的try块看起来像是在问问题,因为格式不正确的文件可能没有被检测到。 一种替代方法是将每个next()调用包装在一个try块中,并设置一个标志来退出外部循环,这看起来似乎很棘手。
其次, while ''.join(item).strip() != '':
非常难看。 有没有更好的方法来testing一个由csv模块parsing的空行?
更新:
我错过了一个影响空行testing的细节。 正如您可能已经猜到的,代码是parsing从Excel导出的制表符分隔文件。 在这种情况下,空行的有趣之处在于它们不是真的空的 – 文件中的所有行都具有相同数量的制表符。 所以如果你在excel文件中有3列,导出的制表符分隔文件中的空行将有2个选项卡,并且csv将把它parsing成['', '', '']
,其中bool
值为True
。
所以对于Ignacio的更漂亮的答案, for row in itertools.takewhile(bool, c):
将不起作用,因为它会阻止文件的其余部分,包括空行和ID行。 for row in itertools.takewhile(lambda x: ''.join(x).strip() != '', c):
确实有效,但是我们又回到了我试图避免的丑陋之处(strip()可能没有必要,但我把它放在安全的一边)。
布莱什。 空行导致一个空的列表。
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))