Python os.path.join () in einer Liste

89

ich kann

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

Aber wenn ich es mache

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

Was vermisse ich hier?

ATOzTOA
quelle

Antworten:

187

Das Problem ist, os.path.joinnimmt kein listals Argument, es muss separate Argumente sein.

Hier kommt *der Splat-Operator ins Spiel ...

ich kann

>>> s = "c:/,home,foo,bar,some.txt".split(",")
>>> os.path.join(*s)
'c:/home\\foo\\bar\\some.txt'
ATOzTOA
quelle
10
etwas mehr Kontext für splat: docs.python.org/2/tutorial/…
A.Wan
3
Beachten Sie, dass ich versucht habe, damit den letzten Teil eines vollständigen Pfads zu entfernen. Es führte zu einem Fehler (auf dem Mac), da der erste Schrägstrich bei fehlte /Users/.... Um es zu lösen, habe ich diesen führenden Schrägstrich manuell hinzugefügt, falls jemand vor dem gleichen Problem steht ...
J0ANMM
22

Angenommen, es joinwurde nicht so entworfen (was es ist, wie ATOzTOA hervorhob), und es wurden nur zwei Parameter benötigt, könnten Sie dennoch das integrierte verwenden reduce:

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

Gleiche Ausgabe wie:

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

Nur aus Gründen der Vollständigkeit und Bildung (und für andere Situationen, in denen *dies nicht funktioniert).

Hinweis für Python 3

reducewurde in das functoolsModul verschoben .

Thorsten Kranz
quelle
2
In Python 3 reducewurde in das functoolsModul verschoben, falls jemand anderes so danach suchte wie ich.
Adam Badura
Vielen Dank für den Hinweis, ich werde meine Antwort anpassen.
Thorsten Kranz
3
Schade, dass Python sich immer mehr vom funktionalen Stil entfernt, anstatt ihn zu umarmen und sich zu öffnen. Der Wechsel reducezu einem Modul ist eine Aussage.
SHernandez
Sogar in 2.7 kann manfrom functools import reduce
duhaime
12

Ich stolperte über die Situation, in der 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 verändert.

Sebastian Mach
quelle
8

Es ist nur die Methode. Du vermisst nichts. Die offizielle Dokumentation zeigt, dass Sie das Entpacken von Listen verwenden können, um mehrere Pfade anzugeben:

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

Beachten Sie die *sIntead von nur sin os.path.join(*s). Die Verwendung des Sternchens löst das Entpacken der Liste aus. Dies bedeutet, dass jedes Listenargument als separates Argument an die Funktion übergeben wird.

Greg
quelle
Schau noch einmal in deinen Link ;-)
Thorsten Kranz
@ Greg es wird auf SO bevorzugt, die relevanten Teile in die Antwort zu kopieren und nicht nur einen Link einzufügen, vielleicht deshalb die Downvotes
SHernandez
2

Dies kann auch als einfache Kartenreduktionsoperation betrachtet werden, wenn Sie dies aus einer funktionalen Programmierperspektive betrachten möchten.

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

reduceist in Python 2.x integriert. In Python 3.x wurde es nach verschoben. itertoolsDie akzeptierte Antwort ist jedoch besser.

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

Nishant
quelle