4

これは簡単なことですが、私はPythonの新規ユーザーなので、ここで少し問題があります。ちなみに私はPython3を使用しています。

次のようなファイルが複数あります。

名前日付年齢性別の色

Name Date Age Sex Color
Ray  May  25.1 M  Gray
Alex Apr  22.3 F  Green
Ann  Jun  15.7 F  Blue

(これはタブで区切られていると仮定します。実際のファイルには約3,000行と17〜18列があることを追加する必要があります)

私がやりたいのは、年齢列の値が23未満のすべての行を選択することです。

この例では、出力は次のようになります。

Name Date Age Sex Color
Alex Apr  22.3 F  Green
Ann  Jun  15.7 F  Blue

これが私がやろうとしたことです:

f = open("addressbook1.txt",'r')
line = f.readlines()
file_data =[line.split("\t")]
f.close()

for name, date, age, sex, color in file_data:
    if age in line_data < 23:
        g = open("college_age.txt",'a')
        g.write(line)
    else:
        h = open("adult_age.txt",'a')
        h.write(line)

理想的には、これらの「アドレスブック」入力ファイルが20〜30個あり、このスクリプトでそれらすべてをループして、23歳未満のすべてのエントリを同じ出力ファイル(「college_age.txt」)に追加する必要があります。私は本当に他の行を保持する必要はありませんが、私はそれらを他に何をすべきかわかりませんでした。

このスクリプトを実行すると、エラーが発生します。

AttributeError: 'list' object has no attribute 'split'

次に、3行目を次のように変更します。

file_data=[line.split("\t") for line in f.readlines()]

そして、それはもはや私にエラーを与えませんが、単に何もしません。開始してから開始します。

何か助けはありますか?:)私はPythonに馬鹿げていることを忘れないでください。

実際のデータには小数があり、整数ではないことを付け加えておく必要があります。それを反映するために上記のデータを編集しました。

4

3 に答える 3

5

ここでの問題は、readlines()2回使用していることです。つまり、データは最初に読み取られ、2回目には何も残されません。

を使用せずにファイルを直接反復処理できますreadlines()。実際、ファイル全体を一度に読み込むことはないため、これがより適切な方法です。

自分がやろうとしていることを今のように使用することで実行できstr.split()ますが、より適切なオプションは、タスク用に設計されcsvモジュールを使用することです。

import csv

with open("addressbook1.txt") as input, open("college_age.txt", "w") as college, open("adult_age.txt", "w") as adult:
   reader = csv.DictReader(input, dialect="excel-tab")
   fieldnames = reader.fieldnames
   writer_college = csv.DictWriter(college, fieldnames, dialect="excel-tab")
   writer_adult = csv.DictWriter(adult, fieldnames, dialect="excel-tab")
   writer_college.writeheader()
   writer_adult.writeheader()
   for row in reader:
       if int(row["Age"]) < 23:
          writer_college.writerow(row)
       else:
          writer_adult.writerow(row)

では、ここで何をしているのでしょうか。まず、ファイルを開くためwithステートメントを使用します。これは、よりPython的で読みやすいだけでなく、例外が発生した場合でも閉じを処理します。

次にDictReader、最初の行をフィールド名として自動的に使用して、ファイルから行を辞書として読み取るを作成します。次に、ライターに分割ファイルに書き戻し、ヘッダーを書き込みます。を使用するのDictReaderは好みの問題です。これは通常、データに頻繁にアクセスする場合(および、列の順序がわからない場合)によく使用されますが、ここでコードを読みやすくします。ただし、標準を使用することもできますcsv.reader()

次に、ファイル内の行をループし、経過時間をチェックして(数値比較を実行できるように、intに変換します)、どのファイルに書き込むかを確認します。ステートメントは私たちのwithためにファイルを閉じます。

複数の入力ファイルの場合:

import csv

fieldnames = ["Name", "Date", "Age", "Sex", "Color"]
filenames = ["addressbook1.txt", "addressbook2.txt", ...]

with open("college_age.txt", "w") as college, open("adult_age.txt", "w") as adult:
   writer_college = csv.DictWriter(college, fieldnames, dialect="excel-tab")
   writer_adult = csv.DictWriter(adult, fieldnames, dialect="excel-tab")
   writer_college.writeheader()
   writer_adult.writeheader()
   for filename in filenames:
       with open(filename, "r") as input:
           reader = csv.DictReader(input, dialect="excel-tab")
           for row in reader:
               if int(row["Age"]) < 23:
                  writer_college.writerow(row)
               else:
                  writer_adult.writerow(row)

複数のファイルを処理するためにループを追加するだけです。フィールド名のリストも追加したことに注意してください。フィールドとファイルからの順序を使用する前に、複数のファイルがあるので、ここでそれを行う方が賢明だと思いました。別の方法は、最初のファイルを使用してフィールド名を取得することです。

于 2012-04-27T22:07:01.297 に答える
0

そのようなファイルを読むにはcsvモジュールを使用する方が良いと思いますhttp://docs.python.org/library/csv.html

于 2012-04-27T22:04:03.310 に答える
-3

ITYM

with open("addressbook1.txt", 'r') as f:
    # with automatically closes
    file_data = ((line, line.split("\t")) for line in f)
    with open("college_age.txt", 'w') as g, open("adult_age.txt", 'w') as h:
        for line, (name, date, age, sex, color) in file_data:
            if int(age) < 23: # float() if it is not an integer...
                g.write(line)
            else:
                h.write(line)

ファイルデータが数回繰り返されているように見える場合があります。しかし、ジェネレータ式のおかげで、file dataは、要求された場合にファイルの次の行を渡すジェネレータにすぎません。そして、forループでそうするように求められます。つまり、forループによって取得されるすべてのアイテムはジェネレーターから取得され、file_data要求に応じて、各ファイル行が完全な行(コピー用)とそのコンポーネント(テスト用)を保持するタプルに変換されます。

代替案は

file_data = ((line, line.split("\t")) for line in iter(f.readline, ''))
  • readlines()ファイルを反復処理するよりも近いです。readline()ファイルの反復とは少し異なる舞台裏での動作として、そうする必要があるかもしれません。

(関数型プログラミングが気に入らない場合はreadline()、空の文字列が返されるまで手動で呼び出すジェネレーター関数を作成することもできます。

また、ネストされたジェネレーターがまったく気に入らない場合は、次のことができます。

with open("addressbook1.txt", 'r') as f, open("college_age.txt", 'w') as g, open("adult_age.txt", 'w') as h:
    for line in f:
        name, date, age, sex, color = line.split("\t")
        if int(age) < 23: # float() if it is not an integer...
            g.write(line)
        else:
            h.write(line)

これはまったく同じです。)

于 2012-04-27T22:08:39.720 に答える