再空リスト

def process_dialect_translation_rules():

    # Read in lines from the text file specified in sys.argv[1], stripping away
    # excess whitespace and discarding comments (lines that start with '##').
    f_lines = [line.strip() for line in open(sys.argv[1], 'r').readlines()]
    f_lines = filter(lambda line: not re.match(r'##', line), f_lines)

    # Remove any occurances of the pattern '\s*<=>\s*'. This leaves us with a 
    # list of lists. Each 2nd level list has two elements: the value to be 
    # translated from and the value to be translated to. Use the sub function
    # from the re module to get rid of those pesky asterisks.
    f_lines = [re.split(r'\s*<=>\s*', line) for line in f_lines]
    f_lines = [re.sub(r'"', '', elem) for elem in line for line in f_lines]

この関数は、ファイルから行を取り出して、 ## で始まる行を削除するなど、行に対していくつかの操作を実行する必要があります。私が実行したい別の操作は、行内の単語の前後にある引用符を削除することです。しかし、このスクリプトの最終行が実行されると、 f_lines は空行になります。何が起こった?

元のファイルの要求された行:

##  English-Geek Reversible Translation File #1
##   (Moderate Geek)
##  Created by Todd WAreham, October 2009

"TV show"    <=> "STAR TREK"
"food"       <=> "pizza"
"drink"      <=> "Red Bull"
"computer"   <=> "TRS 80"
"girlfriend" <=> "significant other"
2
私たちがテストするために元のファイルのいくつかの行を提供できますか?
追加された 著者 mac,
完了しました。ここでの目標は、文字列から引用符を取り除き、最初の値を2番目の値にマッピングする辞書を作成することです。私は他のすべてが働いていると思っていますが、引用符を取り除くことは面倒です。編集:私はまた、f_lines [elem.strip( '"')を使って、elemの行をf_linesにしようとしましたが、これもリスト全体を消去しました。
追加された 著者 mau5padd,

2 答え

Pythonでは、リスト内包の for ループは右から左ではなく左から右で処理されるため、最後の式は次のようになります。

[re.sub(r'"', '', elem) for line in f_lines for elem in line]

リスト内包がループ変数をリークするので、そのままではエラーにはならないので、 line は以前の式のスコープ内にあります。その line が空文字列の場合、結果として空のリストが得られます。

2
追加された
@ jmau5 - 目標の dict ビットが必要な場合は、別の回答として投稿しました。
追加された 著者 mac,
ああ!問題が解決しました。ありがとう。 :)
追加された 著者 mau5padd,

あなたの基本的な問題は、あなたが物事を行うための過度に複雑な方法を選んだことです。ジョブを完了させる最も簡単なツールを使用してください。フィルタ、マップ、ラムダ、読み込み線、およびこれらのリスト内包表記のすべて(必要なもの)は必要ありません。 startswithの代わりにre.matchを使用することは過度のことです。だからst.subrereplaceが仕事をするre.subを使用しています。

with open(sys.argv[1]) as f:
    d = {}
    for line in f:
        line = line.strip()
        if not line: continue # empty line
        if line.startswith('##'): continue # comment line
        parts = line.split('<=>')
        assert len(parts) == 2 # or print an error message ...
        key, value = [part.strip('" ') for part in parts]
        assert key not in d # or print an error message ...
        d[key] = value

ボーナス余分に:あなたは悪い行を確認し、キーを複製する。

0
追加された
@ jmau5 - 私はあなたが新しいことを理解しているので、私はあなたのために3つのことを指摘すれば気にしないことを願っています:(1)宿題であれば、 。割り当てについての助けを求めるのは問題ありませんが、私たちが知っているならば、あなたの学習を最大限にする方法、もっと多くのコメントなどであなたを助けてくれるでしょう...(2)あなたの質問に対する回答が、情報を使用しているかどうかにかかわらず、それらをupvoteすることは良いプラクシスです - 評判は、そんなことを続けるものです! (3)あなたの課題に最高の幸運! :)
追加された 著者 mac,
再モジュールは膨らみの約40%しかありません。
追加された 著者 John Machin,
あなたは line.strip()の代わりに re.sub(r '^ \ s *(。*?)\ s * \ Z'、r '\ 1'、行)
追加された 著者 John Machin,
私はそれが過度に複雑であることに同意するが、私の教授は私に "reモジュールを広範に利用する"ように頼んだ。 :)
追加された 著者 mau5padd,
@mac - これからはやります。唯一の問題は、私はまだ実際にアップアップすることができないということです。 ;)
追加された 著者 mau5padd,