2

これは、1つに2つのコーディングスタイルの質問のようなものです。'objects'が空白行で区切られている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ブロックで囲むと、不適切な形式のファイルが検出されない可能性があるため、問題が発生しているように見えます。1つの代替方法は、各next()呼び出しをtryブロックでラップし、フラグを設定して外側のループを終了することです。これもハッキーのようです。

第二に、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

Blech。空の行は空のリストになります。

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 に答える