Python os.path.join () dalam daftar

97

dapat saya lakukan

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

Tapi, saat aku melakukannya

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

Apa yang kulewatkan di sini?

ATOzTOA
sumber

Jawaban:

197

Masalahnya adalah, os.path.jointidak mengambil listsebagai argumen, itu harus menjadi argumen yang terpisah.

Di sinilah *, operator 'percikan' berperan ...

dapat saya lakukan

>>> s = "c:/,home,foo,bar,some.txt".split(",")
>>> os.path.join(*s)
'c:/home\\foo\\bar\\some.txt'
ATOzTOA
sumber
10
beberapa konteks lagi untuk percikan: docs.python.org/2/tutorial/…
A.Wan
3
Perhatikan bahwa saya mencoba menggunakan ini untuk menghapus bagian terakhir dari jalur lengkap. Ini mengakibatkan kesalahan (di Mac), karena garis miring pertama di /Users/.... Untuk mengatasinya, saya menambahkan garis miring itu secara manual, jika seseorang menghadapi masalah yang sama ...
J0ANMM
23

Dengan asumsi jointidak dirancang seperti itu (seperti yang ditunjukkan ATOzTOA), dan hanya membutuhkan dua parameter, Anda masih bisa menggunakan built-in reduce:

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

Output yang sama seperti:

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

Hanya untuk alasan kelengkapan dan pendidikan (dan untuk situasi lain di mana *tidak berhasil).

Petunjuk untuk Python 3

reducedipindahkan ke functoolsmodul.

Thorsten Kranz
sumber
2
Dalam Python 3 reducedipindahkan ke functoolsmodul jika ada orang lain yang mencarinya seperti saya.
Adam Badura
Terima kasih atas petunjuknya, saya akan menyesuaikan jawaban saya.
Thorsten Kranz
3
Sayangnya python semakin menjauh dari gaya fungsional alih-alih merangkulnya dan membuka diri. pindah reduceke modul adalah pernyataan.
SHernandez
Bahkan di 2,7 orang bisafrom functools import reduce
duhaime
14

Saya tersandung situasi di mana daftarnya mungkin kosong. Dalam hal itu:

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

Perhatikan argumen pertama, yang tidak akan mengubah hasilnya.

Sebastian Mach
sumber
8

Itu hanya metodenya. Anda tidak melewatkan apa pun. The dokumentasi resmi menunjukkan bahwa Anda dapat menggunakan daftar membongkar untuk memasok beberapa jalur:

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

Perhatikan *sintead dari just sin os.path.join(*s). Menggunakan tanda bintang akan memicu pembongkaran daftar, yang berarti bahwa setiap argumen daftar akan diberikan ke fungsi sebagai argumen terpisah.

Greg
sumber
Lebih baik lihat tautan Anda sekali lagi ;-)
Thorsten Kranz
@Greg lebih disukai di SO untuk menyalin bagian yang relevan ke dalam jawaban dan tidak hanya menempelkan tautan, mungkin oleh karena itu suara negatifnya
SHernandez
2

Ini juga dapat dianggap sebagai operasi pengurangan peta sederhana jika Anda ingin menganggapnya dari perspektif pemrograman fungsional.

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

reducedibangun dengan Python 2.x. Dalam Python 3.x itu telah dipindahkan ke itertoolsNamun jawaban yang diterima lebih baik.

Ini telah dijawab di bawah ini tetapi menjawab jika Anda memiliki daftar item yang perlu digabungkan.

Nishant
sumber