2017-09-28 8 views
1

重複しているが一意の名前のファイルのリストを含むファイルがあります。例えば空白行で区切られた行をよりpython的にグループ化する方法

<md5sum> /var/www/one.png 
<md5sum> /var/www/one-1.png 

<md5sum> /var/www/two.png 
<md5sum> /var/www/two-1.png 
<md5sum> /var/www/two-2.png 

目的は以下で終わることです:

[ 
    [ 
     '/var/www/one.png', 
     '/var/www/one-1.png' 
    ], 
    [ 
     '/var/www/two.png', 
     '/var/www/two-1.png', 
     '/var/www/two-2.png' 
    ] 
] 

これは私が以前走ったコマンドからの出力です。今、私はこの出力を処理する必要がある、と私は初心者のために、次のコードを思い付いた:

from pprint import pprint 
DUPES_FILE = './dupes.txt' 

def process_dupes(dupes_file): 
    groups = [[]] 
    index = 0 
    for line in dupes_file: 
     if line != '\n': 
      path = line.split(' ')[1] 
      groups[index].append(path) 
     else: 
      index += 1 
      groups.append([]) 

    pprint(groups) 

with open(DUPES_FILE, 'r') as dupes_file: 
    process_dupes(dupes_file) 

これを書くために、より簡潔な方法はありますか?

+0

ための変数 'index'あるもの? – kogito

+0

これはgroups変数と組み合わせて使用​​されます。 –

+0

実際に出力に行末の文字を保存したいのですか?> –

答えて

3

ファイル全体を変数に読み込みます。 split("\n\n")を使用して重複グループに分割し、split("\n")で分割して各行を取得し、最後に各行をsplit(" ")で分割します。

def process_dupes(dupes_file) 
    contents = dupes_file.read() 
    groups = [[line.split(" ")[1] for line in group.split("\n") if line != ""] for group in contents.split("\n\n")] 
+0

私は次のようになっています:IndexError:リストインデックスが範囲外です –

+0

'group.split()'はファイルの最後の行に空行を含むので、 'if line!=" "'でフィルタリングする必要があります。 – Barmar

1

やや良いバージョンです。これが混乱した場合は、ご使​​用のバージョンの1点の改善がインデックス変数を削除して-1を使用無視され

In [61]: with open(DUPES_FILE, 'r') as dupes_file: 
    ...:  pprint(list(get_groups(dupes_file))) 
    ...:  
    ...:  
[['/var/www/one.png\n', '/var/www/one-1.png\n'], 
['/var/www/two.png\n', '/var/www/two-1.png\n', '/var/www/two-2.png\n']] 

:またグループ

def get_groups(dupes_file): 
    group = [] 
    for line in dupes_file: 
     if line == "\n": 
      if group: 
       yield group 
       group = [] 
     else: 
      md5sum, path = line.split(' ') 
      group.append(path.strip()) 
    if group: 
     yield group 

間に複数の新しい行がある場合の出力を処理しますあなたはいつも最後のリストに追加したいと思う。

次のではなく、最初にメモリに全部を読んで、反復してファイル内のデータを処理する
def process_dupes(dupes_file): 
    groups = [[]] 
    for line in dupes_file: 
     if line != '\n': 
      path = line.split(' ')[1] 
      groups[-1].append(path) 
     else: 
      groups.append([]) 

    pprint(groups) 
+0

パスから '\ n'をトリミングする必要があります。 – Barmar

0

from itertools import groupby 
from pprint import pprint 

DUPES_FILE = './dupes.txt' 

def process_dupes(dupes_file): 
    groups = [ 
     [line.rstrip().split(' ')[1] for line in lines] 
      for blank, lines in groupby(dupes_file, lambda line: line == '\n') 
       if not blank 
    ] 
    pprint(groups) 

with open(DUPES_FILE, 'r') as dupes_file: 
    process_dupes(dupes_file) 

出力:

[['/var/www/one.png', '/var/www/one-1.png'], 
['/var/www/two.png', '/var/www/two-1.png', '/var/www/two-2.png']] 
関連する問題