2009-06-23 13 views
1

私は、私はいくつかの助けを使用することがある問題を持っている私はこのようになりますPythonのリストがあります:私が欲しいものPythonのリストの質問

fail = [ 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\b\\include', 'Test.java'] 
['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\c', 'apa1.txt'] 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'knark.txt'] 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\d', 'Sourcecheck.py'] 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\a\\include', 'svin.txt'] 
['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\a', 'apa2.txt'] 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'apa.txt'] 

sha1 value, directory, filename 

をsha1の値に基づいて、2つの異なるリストにこのコンテンツを分離することですとディレクトリ。例えば。

私はそれが同じsha1の値(とのみ、そのディレクトリ)と同じディレクトリにありますので、リスト duplicate = []に追加する
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'apa.txt'] 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'knark.txt'] 

。他のリストに追加したいエントリの残りの部分、たとえばdiff = []は、sha1の値は同じですがディレクトリは異なるためです。

私はちょっと論理が失われているので、私が得ることができるすべてのことは感謝するでしょう!

EDIT:この問題を認識するためにタイプミス、最終値(ファイル名)が1リスト要素(100%が間違っています)をSilentGhostに修正しました。

+0

あなたが少し明確に何をしようとして説明しよう。 –

+0

あなたがしたいことはまったく明確ではありません。期待される完全なアウトプットは何ですか? –

+0

ファイル名が大好きです、笑。 – Skurmedel

答えて

3
duplicate = [] 
# Sort the list so we can compare adjacent values 
fail.sort() 
#if you didn't want to modify the list in place you can use: 
#sortedFail = sorted(fail) 
#  and then use sortedFail in the rest of the code instead of fail 
for i, x in enumerate(fail): 
    if i+1 == len(fail): 
     #end of the list 
     break 
    if x[:2] == fail[i+1][:2]: 
     if x not in duplicate: 
      duplicate.add(x) 
     if fail[i+1] not in duplicate: 
      duplicate.add(fail[i+1]) 
# diff is just anything not in duplicate as far as I can tell from the explanation 
diff = [d for d in fail if d not in duplicate] 
あなたの例を入力して

duplicate: [ 
       ['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', ['apa.txt']], 
       ['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'knark.txt'] 
      ] 

diff: [ 
      ['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\a', ['apa2.txt']], 
      ['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\c', 'apa1.txt'], 
      ['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\a\\include', ['svin.txt']], 
      ['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\b\\include', 'Test.java'], 
      ['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\d', 'Sourcecheck.py'] 
     ] 

ので、おそらく私が何かを逃したが、私はこれがあなたが求めていたものだと思います。

+0

ありがとう、私はこのロジックと関数を見て見て、うまく動作します! – Anders

+0

@Robbie - 私は 'diff'の計算が正しいとは思わない。私の理解では、ハッシュが同じであるにもかかわらず項目が入るだけですが、パスは異なります。しかし、これはほぼ同じ方法で計算することができますが、第2の条件を '' if [0] == fail [i + 1] [0]とx [1]!= fail [i + 1] [ 1]: '。 –

1

すべての値をループして内部ループを使用してディレクトリを比較し、ディレクトリが同じ比較値の場合はリストを割り当てます。これはあなたにそれを整理するためのまともなn^2アルゴリズムを与えるでしょう。多分、この未テストコードのよう

>>>for i in range(len(fail)-1): 
... dir = fail[i][1] 
... sha1 = fail[i][0] 
... for j in range(i+1,len(fail)): 
...  if dir == fail[j][1]: #is this how you compare strings? 
...   if sha1 == fail[j][0]: 
...   #remove from fail and add to duplicate and add other to diff 

は再びコードがテストされていません。

0

辞書を使ってshaとディレクトリでグループ化する別の方法です。これにより、ファイル名のランダムなリストも取り除かれます。

new_fail = {}  # {sha: {dir: [filenames]}} 
for item in fail: 
    # split data into it's parts 
    sha, directory, filename = item 

    # make sure the correct elements exist in the data structure 
    if sha not in new_fail: 
     new_fail[sha] = {} 
    if directory not in new_fail[sha]: 
     new_fail[sha][directory] = [] 

    # this is where the lists are removed from the file names 
    if type(filename) == type([]): 
     filename = filename[0] 

    new_fail[sha][directory].append(filename) 

diff = [] 
dup = [] 

# loop through the data, analyzing it 
for sha, val in new_fail.iteritems(): 
    for directory, filenames in val.iteritems(): 

     # check to see if the sha/dir combo has more than one file name 
     if len(filenames) > 1: 
      for filename in filenames: 
       dup.append([sha, directory, filename]) 
     else: 
      diff.append([sha, dir, filenames[0]]) 

それを印刷するには:

print 'diff:' 
for i in diff: 
    print i 
print '\ndup:' 
for i in dup: 
    print i 

サンプル・データは、次のようになります。次のコードサンプルで

 
diff: 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\d', 'Sourcecheck.py'] 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\b\\include', 'Test.java'] 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\a\\include', 'svin.txt'] 
['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\a', 'apa2.txt'] 
['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\c', 'apa1.txt'] 

dup: 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'knark.txt'] 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'apa.txt']
+0

また、ありがとう、私はこれも見ていきます。 – Anders

1

、私はSHA1およびディレクトリ名に基づいてキーを使用して検出しますユニークで重複したエントリとハウスキーピングのスペア辞書。

# Test dataset 
fail = [ 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\b\\include', 'Test.java'], 
['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\c', 'apa1.txt'], 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'knark.txt'], 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\d', 'Sourcecheck.py'], 
['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\a\\include', ['svin.txt']], 
['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\a', ['apa2.txt']], 
['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', ['apa.txt']], 
] 


def sort_duplicates(filelist): 
    """Returns a tuplie whose first element is a list of unique files, 
    and second element is a list of duplicate files. 
    """ 
    diff = [] 
    diff_d = {} 

    duplicate = [] 
    duplicate_d = {} 

    for entry in filelist: 

     # Make an immutable key based on the SHA-1 and directory strings 
     key = (entry[0], entry[1]) 

     # If this entry is a known duplicate, add it to the duplicate list 
     if key in duplicate_d: 
      duplicate.append(entry) 

     # If this entry is a new duplicate, add it to the duplicate list 
     elif key in diff_d: 
      duplicate.append(entry) 
      duplicate_d[key] = entry 

      # And relocate the matching entry to the duplicate list 
      matching_entry = diff_d[key] 
      duplicate.append(matching_entry) 
      duplicate_d[key] = matching_entry 
      del diff_d[key] 
      diff.remove(matching_entry) 

     # Otherwise add this entry to the different list 
     else: 
      diff.append(entry) 
      diff_d[key] = entry 

    return (diff, duplicate) 

def test(): 
    global fail 
    diff, dups = sort_duplicates(fail) 
    print "Diff:", diff 
    print "Dups:", dups 

test() 
+0

ありがとう、私はこれも見ていきます。 – Anders

0

私は受け入れ答えは(Pythonの内部ソートが私の辞書徒歩よりも高速でなければなりません)多少、より効率的になると信じて、私はすでにこの思い付いたことから、私もそれを掲示することがあります。 :-)

この手法では、ソートと明示的な比較の両方を避けるために、マルチレベル辞書を使用しています。

hashes = {} 
diff = [] 
dupe = [] 

# build the dictionary 
for sha, path, files in fail: 
    try: 
     hashes[sha][path].append(files) 
    except KeyError: 
     try: 
      hashes[sha][path] = [files] 
     except: 
      hashes[sha] = dict((path, [files])) 

for sha, paths in hashes.iteritems(): 
    if len(paths) > 1: 
     for path, files in paths.iteritems(): 
      for file in files: 
       diff.append([sha, path, file]) 
    for path, files in paths.iteritems(): 
     if len(files) > 1: 
      for file in files: 
       dupe.append([sha, path, file]) 

結果は以下のようになります。

diff = [ 
    ['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\d', 'Sourcecheck.py'], 
    ['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\b\\include', 'Test.java'], 
    ['da39a3ee5e6b4b0d3255bfef95601890afd80709', 'ron\\a\\include', ['svin.txt']], 
    ['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\a', ['apa2.txt']], 
    ['b5cc17d3a35877ca8b76f0b2e07497039c250696', 'ron\\c', 'apa1.txt'] 
] 
dupe = [ 
    [['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', 'knark.txt'], 
    ['95d1543adea47e88923c3d4ad56e9f65c2b40c76', 'ron\\c', ['apa.txt']] 
] 
+0

非常に感謝しています!すべての入力は素晴らしい、私は幸せを学ぶ:)! – Anders

+0

私はあなたがあなたの "ビルド辞書"セクションをやったのが好きです。私と比べて非常にきちんとしています。私は特にループ文で値をアンパックするのが好きです。 – tgray

関連する問題