2

这是两个编码风格问题合二为一。我有一个 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 会将其['', '', '']解析boolTrue.

所以 wrt Ignacio 的更漂亮的答案是for row in itertools.takewhile(bool, c):行不通的,因为它会占用文件的其余部分,包括空行和 ID 行。for row in itertools.takewhile(lambda x: ''.join(x).strip() != '', c):确实有效,但我们又回到了我试图避免的丑陋(strip() 可能不是必需的,但为了安全起见,我把它放进去)。

4

1 回答 1

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))
于 2012-07-27T01:04:04.063 回答