2016-12-09 1 views
0

Ich versuche, einige Dateipfade von 2 list Elemente in Python zuzuordnen. Diese Dateien haben einen Teil ihres Namens identisch, während die Erweiterung und einige zusätzliche Wörter unterschiedlich sind.Dateiname Zeichenfolge Vergleich in der Liste Suche schlägt fehl [Python]

Dies bedeutet, dass die Dateierweiterung, zusätzliche Zeichen und deren Position abweichen können. Die Dateien befinden sich in verschiedenen Ordnern, daher unterscheidet sich ihr Dateiname. Was ist genau gleich: ihre Nummerierung Index: 0033, 0061 zum Beispiel.

Beispielcode:

original_files = ['C:/0001.jpg', 
    'C:/0033.jpg', 
    'C:/0061.jpg', 
    'C:/0080.jpg', 
    'C:/0204.jpg', 
    'C:/0241.jpg'] 

related_files = ['C:/0001_PM.png', 
    'C:/0033_PMA.png', 
    'C:/0033_NM.png', 
    'C:/0061_PMLTS.png', 
    'C:/0080_PM.png', 
    'C:/0080_RS.png', 
    'C:/0204_PM.png'] 

for idx, filename in enumerate(original_files):  
     related_filename = [s for s in (related_files) if filename.rsplit('/',1)[1][:-4] in s]  
     print(related_filename)  

Bei filename = 'C:/0241.jpg' sollte es [] zurückkehren, sondern es gibt alle Dateinamen aus related_files.

Aus Datenschutzgründen habe ich nicht die gesamte Filepath Post, sondern nur die Namen der Dateien. In diesem Beispiel funktioniert der Vergleich, aber für schlägt der gesamte Dateipfad fehl.

Ich nehme an, meine Vergleichsbedingung ist nicht korrekt, aber ich weiß nicht, wie man es schreibt.

Hinweis: Ich suche nach etwas mit so wenig Codezeilen wie möglich, um dies zu tun.

+0

'während die Erweiterung und einige zusätzliche Wörter anders sind' Wir brauchen hier mehr Informationen. Was genau wird gleich sein, was kann anders sein? –

+0

@LutzHorn mein Schlechter. Die Dateierweiterung und ihre Position können abweichen. Die Dateien befinden sich in verschiedenen Ordnern, daher unterscheidet sich ihr Dateiname. Was ist genau gleich: Ihr Nummerierungsindex: zum Beispiel '0033'. – Roxanne

+0

Stimmt es, dass der Name jeder Datei mit einigen Zahlen beginnt, gefolgt von einem '_'? Sind diese Zahlen die eindeutige Kennung, die verwendet werden soll, um die zugehörige Datei zu finden? –

Antwort

0

Ich schlage vor, etwas entlang der Linie von

from collections import defaultdict 

original_files = ['C:/0001.jpg', 
    'C:/0033.jpg', 
    'C:/0061.jpg', 
    'C:/0080.jpg', 
    'C:/0204.jpg', 
    'C:/0241.jpg'] 

related_files = ['C:/0001_PM.png', 
    'C:/0033_PMA.png', 
    'C:/0033_NM.png', 
    'C:/0061_PMLTS.png', 
    'C:/0080_PM.png', 
    'C:/0080_RS.png', 
    'C:/0204_PM.png'] 

def key1(filename): 
    return filename.rsplit('/', 1)[-1].rsplit('.', 1)[0] 

def key2(filename): 
    return key1(filename).split('_', 1)[0] 

d = defaultdict(list) 
for x in related_files: 
    d[key2(x)].append(x) 

for x in original_files: 
    related = d.get(key1(x), []) 
    print(x, '->', related) 

In key1() und key2() Sie abwechselnd os.path Funktionen oder pathlib.Path Methoden nutzen könnten.

+0

Diese Antwort geht davon aus, dass ich nur '2 Zeichen' nach' _' in 'relative_files' habe, aber das ist nicht der Fall. Die Anzahl der Zeichen nach dem _ _ ist variabel. Ich aktualisiere meinen Beispielcode. – Roxanne

+0

Ok, ich habe meine Antwort über – Gribouillis

+0

aktualisiert. Das ist gut, ABER wie mache ich 'related = d.get (key1 (x), None)', um alle ** verwandten Dateinamen abzurufen. Zum Beispiel möchte ich für 'x = C: \ 0033.jpg'' related = ['C: /0033_PMA.png', 'C: /0033_NM.png'] 'haben. – Roxanne

0

Für Python 3.X können Sie versuchen, diese zu nutzen:

for origfiles in original_files: 
    for relfiles in related_files: 
     if origfiles[3:6] == relfiles[3:6]: 
      print(origfiles) 
+1

Dies ist nicht korrekt. Die Namen unterscheiden sich nicht nur in der Erweiterung. –

+0

@Lutz Horn yeah Ich lese gerade den neuen Schnitt, den er jetzt angibt, was wirklich angepasst werden muss. Ich werde meine Antwort ein wenig bearbeiten, aber die Struktur würde immer noch bleiben. –

0

Nutzen Sie defaultdict.

import os, re 
from collections import defaultdict 

stragglers = [] 
grouped_files = defaultdict(list) 
file_index = re.compile('([0-9]+)') 

for f in original_files + related_files: 
    m = file_index.match(os.path.split(f)[1]) 
    if m: 
     grouped_files[m.group(1)].append(f) 
    else: 
     stragglers.append(f) 

Sie haben jetzt grouped_files, ein dict (oder Wörterbuch-like object) von Schlüssel-Wert-Paaren, wo der Schlüssel die regex abgestimmt ist Teil des Dateinamens und der Wert eine Liste von passenden Dateinamen.

for x in grouped_files.items(): 
    print(x) 
# ('0204', ['C:/0204.jpg', 'C:/0204_PM.png']) 
# ('0001', ['C:/0001.jpg', 'C:/0001_PM.png']) 
# ('0033', ['C:/0033.jpg', 'C:/0033_PM.png']) 
# ('0061', ['C:/0061.jpg', 'C:/0061_PM.png']) 
# ('0241', ['C:/0241.jpg']) 
# ('0080', ['C:/0080.jpg', 'C:/0080_PM.png']) 

In stragglers haben Sie Dateinamen, die nicht Ihren regulären Ausdruck entsprechen.

print(stragglers) 
# [] 
+0

@Roxanne Hier ist eine Lösung, es wird auch auf wechselnden Ordnern arbeiten. – chriscberks

+0

Ich würde wirklich gerne eine Lösung, die direkt ** nur ** die passenden 'relative_files' für jedes' Element' aus 'original_files' zurückgibt. Wenn dem 'original_file'-Element keine relative Datei zugeordnet ist, möchte ich es nicht an die endgültige Liste anhängen. – Roxanne

+0

@Roxanne Könnte '[x [1] für x in grouped_files.values ​​() wenn len (x)> 1]' von hier aus tun. Es gibt einen besseren Weg. – chriscberks

0

Hier ist eine Lösung, die nur die passenden related_files zurückgibt.

import os, re 

def get_index(filename): 
    m = re.match('([0-9]+)', os.path.split(filename)[1]) 
    return m.group(1) if m else False 

indexes = filter(bool, map(get_index, original_files)) 
[f for f in related_files if get_index(f) in indexes] 
Verwandte Themen