2017-09-22 7 views
1

Wie diese Umbenennung Problem mit etwas Einmaliges wie "_DUPLICATED_#NO" die Namen Duplikate zu lösen, ohne Rückgriff sein müssen, um die Umbenennung einzigartig, wenn Sie fertig, und vorzugsweise mit iterativen Zahlen bezeichnen Anzahl von DuplikatenPython Umbenennung Duplikate

from collections import defaultdict 

l = ["hello1","hello2","hello3", 
    "hello","hello","hello"] 

tally = defaultdict(lambda:-1) 
for i in range(len(l)): 
    e = l[i] 
    tally[e] += 1 
    if tally[e] > 0: 
     e += str(tally[e]) 
    l[i] = e 
print (l) 

Ergebnisse:

['hello1', 'hello2', 'hello3', 'hello', 'hello1', 'hello2'] 

wie Sie sehen können, sind die Namen nicht eindeutig zuzuordnen

Antwort

4

Dies scheint einfach genug. Sie beginnen mit einer Liste von Dateinamen:

l = ["hello1","hello2","hello3", 
    "hello","hello","hello"] 

Dazu durchlaufen sie Dateinamen fertig, eine hintere Zahl um 1 erhöht wird, wenn ein Duplikat gefunden wird.

result = {} 
for fname in l: 
    orig = fname 
    i=1 
    while fname in result: 
     fname = orig + str(i) 
     i += 1 
    result[fname] = orig 

Dies sollten Sie mit einem Wörterbuch lassen wie:

{"hello1": "hello1", 
"hello2": "hello2", 
"hello3": "hello3", 
"hello": "hello", 
"hello4": "hello", 
"hello5": "hello"} 

Natürlich, wenn Sie auf die doppelte Namen über die Abbildung der Vorlagen nicht kümmern, können Sie diesen Teil fallen.

result = set() 
for fname in l: 
    orig = fname 
    i=1 
    while fname in result: 
     fname = orig + str(i) 
     i += 1 
    result.add(fname) 

Wenn Sie eine Liste später wollen, dann werfen Sie es einfach so.

final = list(result) 

Beachten Sie, dass, wenn Sie Dateien erstellen, das ist genau das, was das tempfile Modul zu tun, ist so konzipiert.

import tempfile 

l = ["hello1","hello2","hello3", 
    "hello","hello","hello"] 

fs = [tempfile.NamedTemporaryFile(prefix=fname, delete=False, dir="/some/directory/") for fname in l] 

Das wird schön Inkrementieren Dateinamen nicht schaffen, aber sie sind garantiert eindeutig, und fs wird eine Liste der (offenen) Dateiobjekte, anstatt eine Liste von Namen, obwohl NamedTemporaryFile.name Sie den Dateinamen geben.

+2

@PRMoureu behoben. Whoops, Algorithmen sind schwer;) Das wird '['hallo1', 'hallo1']' in '['hallo1', 'hallo11']' verwandeln, aber ich kann mir keine großartige Möglichkeit vorstellen, eine Lösung zu verallgemeinern, die das würde erzeuge '['hallo1', 'hallo2']' in einer Weise, die andere weniger offensichtliche Kantenfälle nicht unterbricht. –

+1

das ist in Ordnung, gut gemacht, habe nicht daran gedacht zu verwenden, während> _ < – citizen2077

+1

@new_to_coding meine edit überprüfen, wenn Sie dies verwenden, um Dateien zu erstellen. –