Python os.path.join () in un elenco


97

posso fare

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

Ma quando lo faccio

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

Cosa mi manca qui?

Risposte:


197

Il problema è os.path.joinche non accetta un listargomento, devono essere argomenti separati.

È qui *che entra in gioco l'operatore 'splat' ...

posso fare

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

10
un po 'più di contesto per splat: docs.python.org/2/tutorial/…
A.Wan

3
Nota che ho provato a usarlo per rimuovere l'ultima parte di un percorso completo. Si è verificato un errore (in Mac), poiché mancava la prima barra in /Users/.... Per risolverlo, ho aggiunto quella barra iniziale manualmente, nel caso qualcuno
dovesse

23

Supponendo che joinnon sia stato progettato in questo modo (cosa che è, come ha sottolineato ATOzTOA), e ci sono voluti solo due parametri, è comunque possibile utilizzare il built-in reduce:

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

Stesso output di:

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

Solo per completezza e motivi educativi (e per altre situazioni in cui *non funziona).

Suggerimento per Python 3

reduceè stato spostato nel functoolsmodulo.


2
In Python 3 è reducestato spostato nel functoolsmodulo nel caso in cui qualcun altro lo stesse cercando come me.
Adam Badura

Grazie per il suggerimento, aggiusterò la mia risposta.
Thorsten Kranz

3
peccato che il pitone si allontani sempre di più dallo stile funzionale invece di abbracciarlo e aprirsi. spostarsi reducesu un modulo è un'affermazione.
SHernandez

Anche in 2.7 si puòfrom functools import reduce
duhaime

14

Sono inciampato nella situazione in cui l'elenco potrebbe essere vuoto. In quel caso:

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

Nota il primo argomento, che non altererà il risultato.


8

È solo il metodo. Non ti manca niente. La documentazione ufficiale mostra che è possibile utilizzare lo spacchettamento della lista per fornire diversi percorsi:

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

Nota l' *sintead di just sin os.path.join(*s). L'uso dell'asterisco attiverà la decompressione della lista, il che significa che ogni argomento della lista verrà fornito alla funzione come argomento separato.


Meglio esaminare ancora una volta il tuo link ;-)
Thorsten Kranz

@Greg è preferibile su SO copiare le parti pertinenti nella risposta e non incollare solo un collegamento, forse quindi i
voti negativi

2

Questa può anche essere pensata come una semplice operazione di riduzione della mappa se si desidera pensarla da una prospettiva di programmazione funzionale.

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

reduceè integrato in Python 2.x. In Python 3.x è stato spostato in itertoolsTuttavia la risposta accettata è migliore.

Questo è stato risposto di seguito ma rispondendo se si dispone di un elenco di elementi che devono essere uniti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.