2017-03-16 7 views
1

私は初心者です(2.7)。 だからここに私のファイルです:CSVは重複して&アルゴリズムの "パラドックス"をPythonで修正します

data, 1234, data 
data, 6868, data 
data, 3545, data 
data, 6868, data 
data, 7777, data 
data, 3545, data 

私は(唯一の2列目に)複製してそのように、重複の+1 1をインクリメントチェックしたい:

data, 1234, data 
data, 6868, data 
data, 3545, data 
data, 6869, data 
data, 7777, data 
data, 3546, data 

私はこのような何かをしたが、

entries = set() 
for row in reader: 
    key = row[2] 
    if key in entries: 
     aaa = row[2] 
     bbb = int(aaa) + 1 
     ccc = str(bbb) 
     entries.add(ccc) 
    else: 
     entries.add(key) 
    writer.writerow(row) 

私はこれを行う方法を見ていません。

しかし、私は他の質問について質問しています。増えた数字が現在重複している場合は、どうすれば確認できますか?それは無限ループを作成しませんか?

+0

の答えの一つは、以下の問題が修正された場合、それを受け入れる必要があります(該当する回答の横にあるチェックマークをクリックしてください)。それは2つのことをします。あなたの問題があなたの満足のために解決されたことを誰にでも知らせることができます。詳しい説明は[here](http://meta.stackexchange.com/a/5235)を参照してください。 –

答えて

1

ファイルを反復するときに、列2の値をsetに格納し、繰り返し値が発生した場合は、値が一意になるまでwhileを使用して1ずつ増やします。新しい値を保存し、そしてcsv.writerを使用してファイルに行全体を書く:

import csv 

data = set() 
with open ('task1.txt', 'rb') as file_in, open ('output.txt', 'wb') as fileout: 
    reader = csv.reader(file_in) 
    writer = csv.writer(fileout) 
    for line in reader: 
     idx = int(line[1]) 
     while idx in data: 
      idx += 1 
     data.add(idx) 
     line[1] = str(idx) 

     writer.writerow(line) 

注:Python2.7では、我々はファイルハンドルbufferモード(すなわちrb代わりrのを開くが、これはのpython3では不要です。

+0

助けてくれてありがとう。 "idx + = 1"の "IndentationError:インデントが外側インデントレベルと一致しません"というエラーが表示される – csvunleasher

+0

@csvunleasher pythonは厳密にインデントする方法です。ブロックを作成するときに一貫したインデントスペースを使用します。タブを一貫して使用し、もう一度試してみてください。 – saikumarm

+0

恥ずかしいですが、これはインクリメントエラーです。 "TypeError: 'newline'はこの関数の無効なキーワード引数です。 – csvunleasher

1

無限のデータを持たない限り、無限ループは作成されません:)あなたのコードは近いです - if ... elseの代わりにwhile with an else clauseを使用して既存の番号と衝突する増分数を処理できます。また、rowを新しい鍵で更新する必要があります。

ここでは、テストしやすくするために、文字列からデータを読み取るバージョンがあります。

import csv 

table = '''\ 
data, 6870, data 
data, 6869, data 
data, 1234, data 
data, 6868, data 
data, 3545, data 
data, 6868, data 
data, 7777, data 
data, 3545, data 
''' 

reader = csv.reader(table.splitlines(), skipinitialspace=True) 
entries = set() 
for row in reader: 
    print(' IN', row) 
    while row[1] in entries: 
     row[1] = str(int(row[1]) + 1) 
    else: 
     entries.add(row[1]) 
    print('OUT', row, end='\n\n') 

出力は

IN ['data', '6870', 'data'] 
OUT ['data', '6870', 'data'] 

IN ['data', '6869', 'data'] 
OUT ['data', '6869', 'data'] 

IN ['data', '1234', 'data'] 
OUT ['data', '1234', 'data'] 

IN ['data', '6868', 'data'] 
OUT ['data', '6868', 'data'] 

IN ['data', '3545', 'data'] 
OUT ['data', '3545', 'data'] 

IN ['data', '6868', 'data'] 
OUT ['data', '6871', 'data'] 

IN ['data', '7777', 'data'] 
OUT ['data', '7777', 'data'] 

IN ['data', '3545', 'data'] 
OUT ['data', '3546', 'data'] 

スクリプトの開始時にこれを追加のPython 2にこのコードを実行するには、次の

from __future__ import print_function 
+0

ありがとう@PM 2Ring、これは解決策です。私はこれを試しました: 'file_inとしてopen( 'result4.csv'、 'r')、fileoutとしてopen( 'result5.csv'、 'w'): \t reader = csv.reader(file_in.splitlines )、skipinitialspace = TRUE) \tエントリ=セット()リーダーにおける行の \t: \t \t行[4]エントリにある間: \t \t \t行[4] = STR(INT(行[4])+ 1) \t他\t: \t \t \t entries.add(行[4]) \t \t writer.writerow(row) ' ファイルは属性分割線ではありません – csvunleasher

+0

@csvunleasherコメント内で複数行のコードを読むのは本当に難しいです。将来は、あなたの質問の末尾に、おそらく '


'タグの後に追加してください。あなたは '.splitline()'を使ってはいけません。私は 'table'文字列をリストに変換するために使用しました。 CSV Readerはリストまたはファイル(またはファイルのようなオブジェクト)を受け入れることができます。 'reader = csv.reader(file_in、skipinitialspace = True)'を実行するだけです。しかし、両方のファイルをバイナリモードでオープンする必要があります。 'open( 'result4.csv'、 'rb')'と 'open( 'result5.csv'、 'wb')' –

+0

@csvunleasher FWIW、 'skipinitialspace = True 'は、カンマ区切り記号の直後のスペースを無視するようにReaderに指示します。 –

関連する問題