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?

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'

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 .


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.


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.


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.