2013-02-12 23 views
46

IPython os.path.join() auf einer Liste

>>> os.path.join("c:/","home","foo","bar","some.txt") 
'c:/home\\foo\\bar\\some.txt' 

tun können, aber, wenn ich

tun
>>> s = "c:/,home,foo,bar,some.txt".split(",") 
>>> os.path.join(s) 
['c:/', 'home', 'foo', 'bar', 'some.txt'] 

Was bin ich hier?

Antwort

94

Das Problem ist, os.path.join nimmt keine list als Argument, es muss separate Argumente sein.

Hier *, die 'Splat' Betreiber ins Spiel kommen ...

kann ich

>>> s = "c:/,home,foo,bar,some.txt".split(",") 
>>> os.path.join(*s) 
'c:/home\\foo\\bar\\some.txt' 
+7

etwas mehr Kontext für splat: https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists –

+1

Beachten Sie, dass ich versuchte, dies zu verwenden, um den letzten Teil eines vollständigen Pfads zu entfernen. Dies führte zu einem [Fehler] (http: // stackoverflow.com/questions/31693272/errno-2-using-python-shutil-py-nicht-so-Datei-oder-Verzeichnis-für-Datei-Ziel) (in Mac), da es den ersten Schrägstrich bei '/ Users fehlte/... '. Um es zu lösen, habe ich diesen Schrägstrich manuell hinzugefügt, falls jemand das selbe Problem hat ... – J0ANMM

4

Es ist nur die Methode tun. Du verpasst nichts. Die official documentation zeigt, dass Sie die Liste verwenden können Auspacken mehrere Pfade liefern:

s = "c:/,home,foo,bar,some.txt".split(",") 
os.path.join(*s) 

Notiere die *s intead von nur s in os.path.join(*s). Die Verwendung des Sternchens löst das Entpacken der Liste aus, was bedeutet, dass jedes Listenargument der Funktion als separates Argument übergeben wird.

+0

Schau lieber mal in deinen Link ;-) –

+0

@ThorstenKranz Ernsthaft? Der Link funktioniert völlig. – Greg

+0

@Greg es ist am SO bevorzugt, die relevanten Teile in die Antwort zu kopieren und nicht nur einen Link einzufügen, vielleicht deshalb die Downvotes – SHernandez

14

join Unter der Annahme, wurde nicht so ausgelegt (was es ist, wie ATOzTOA wies darauf hin), und es dauerte nur zwei Parameter, Sie immer noch den eingebauten in reduce verwenden: wie

>>> reduce(os.path.join,["c:/","home","foo","bar","some.txt"]) 
'c:/home\\foo\\bar\\some.txt' 

Gleichen Ausgang :

>>> os.path.join(*["c:/","home","foo","bar","some.txt"]) 
'c:/home\\foo\\bar\\some.txt' 

Nur der Vollständigkeit halber und pädagogischen Gründen (und für andere Situationen, in denen * nicht funktioniert).

Hinweis für Python 3 Für Python 3 wurde reduce zum functools Modul bewegt.

+1

In Python 3 wurde 'reduce' in' functools' Modul verschoben falls jemand anderes danach suchte Ich war. –

+0

Vielen Dank für den Hinweis, ich werde meine Antwort anpassen. –

+2

schade, dass Python mehr und mehr vom funktionalen Stil weggeht, anstatt es zu umarmen und zu öffnen. das Verschieben von 'reduce' weg zu einem Modul ist eine Aussage. – SHernandez

6

Ich stolperte über die Situation, wo die Liste leer sein könnte. In diesem Fall:

os.path.join('', *the_list_with_path_components) 

Beachten Sie das erste Argument, das das Ergebnis nicht ändern wird.

0

Dies kann auch als eine einfache Karte Operation reduzieren gedacht werden, wenn Sie es aus einer funktionalen Programmierung Perspektive denken möchten.

import os 
folders = [("home",".vim"),("home","zathura")] 
[reduce(lambda x,y: os.path.join(x,y), each, "") for each in folders] 

reduce ist in Python 2.x integriert. In Python 3.x wurde es nach itertools verschoben. Die angenommene Antwort ist jedoch besser.

Dies wurde unten beantwortet, aber beantwortet, wenn Sie eine Liste von Elementen haben, die verbunden werden müssen.

Verwandte Themen