2016-08-21 1 views
1

In meinem Programm habe ich einen Codeabschnitt, der in einem der Verzeichnisse meines Computers nach Pickle-Dateien sucht und ihre Namen in eine Liste einfügt . Danach versuche ich, die Dateierweiterung ".pickle" von jedem der Dateinamen in der Liste zu entfernen, aus Gründen, die hier nicht erläutert werden. Nach dem Durchlaufen der Liste und dem Neudefinieren jedes Elements als das, was es sein würde, wenn es in die eingebaute Funktion "str.replace" übergeben würde und die ".pickle" -Zeichenkette durch "" ersetzt wird, scheinen sich die Namen in der Liste nicht geändert zu haben . Hier ist mein Code:str.replace scheint nicht richtig zu funktionieren, wenn die Zielzeichenfolge in einer Liste enthalten ist

import os 
file_names = [file for file in os.listdir("C:/~~/dir") if file.endswith(".pickle")] 
for each in file_names: 
    each = each.replace(".pickle","") 

Die eine Beize-Datei, die ich in der frühen Phase meines Programms der Entwicklung verwende, ist das einzige in dem Verzeichnis.
Das Programm hat keine Fehler ausgelöst.

Der Name der Datei selbst „debugger.pickle“ genannt, und wenn die „dateinamen“ -Liste Druck druckt es

['debugger.pickle'] 

statt

nur
['debugger'] 

das mein gewünschtes Ergebnis ist.

+4

Einstellen eine Variable zu einem Listenelement und dann die Variable Neuzuweisung der Liste nicht ändern:

import glob import os original_files = glob.glob(r'C:/foo/blah/*.pickle') files = [os.path.basename(os.path.splitext(i)[0]) for i in original_files] 

Sie es auch kombinieren können. – Barmar

Antwort

3

each = each.replace(".pickle","") erstellt eine neue Zeichenfolge und bindet sie an den Namen each. Dies hat keine Auswirkungen auf das ursprüngliche String-Objekt in file_names.

Wenn die .replace Methode seine String-in-place mutiert dann

for each in file_names: 
    each.replace(".pickle","") 

funktionieren würde, aber dieser Code nicht wirklich tun, was Sie wollen, weil Python Strings unveränderlich sind.

So müssen Sie die beschnittenen Strings speichern, die einfache Art und Weise zu tun, ist mit einer Liste Verständnis:

file_names = [each.replace(".pickle","") for each in file_names] 

Beachten Sie, dass dies das ursprüngliche file_names Liste Objekt mit einem neuen Objekt ersetzt. Wenn Sie möchten, anstatt die ursprüngliche file_names Objekt ändern können Sie

file_names[:] = [each.replace(".pickle","") for each in file_names] 

tun, die etwas weniger effizient ist (und langsamer), aber es kann nützlich sein, wenn Sie andere Objekte haben, die sich auf die ursprüngliche file_names Objekt.

+1

Diese Antwort bietet eine Lösung für das Problem der 'Datei-Namen' nicht geändert wird, aber einen irreführenden Grund gibt. Es ist nicht, weil "Strings unveränderlich" sind - vermutlich weiß das OP dies, da sie versuchen, "each" in der Schleife neu zuzuweisen. Der Fehler ist, dass OP denkt, dass "each" in jeder Iteration eine Referenz auf das Mitglied in 'file_names' ist, wenn es tatsächlich nur der Wert während jeder Iteration ist. – Jmills

+0

@TheCardCheat: Ich stimme zu, dass meine ursprüngliche Erklärung irreführend sein könnte, also habe ich meine Antwort geändert.Hoffentlich ist es jetzt weniger irreführend, aber wenn Sie irgendwelche Vorschläge haben, lassen Sie es mich wissen. –

0

Sie können Artikel nicht inline austauschen; versuchen Karte oder eine Liste Verständnis über die Liste neu zu erstellen:

files = [os.path.basename(os.path.splitext(i)[0]) for i in glob.iglob(r'C:/foo/*.pickle')] 
Verwandte Themen