Python os.path.join () trên danh sách


97

tôi có thể làm

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

Nhưng khi tôi làm

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

Tôi còn thiếu gì ở đây?

Câu trả lời:


197

Vấn đề là, os.path.joinkhông coi một listđối số nào, nó phải là các đối số riêng biệt.

Đây là nơi *, toán tử 'splat' phát huy tác dụng ...

tôi có thể làm

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

10
một số bối cảnh nhiều hơn cho splat: docs.python.org/2/tutorial/...
A.Wan

3
Lưu ý rằng tôi đã cố gắng sử dụng điều này để xóa phần cuối cùng của đường dẫn đầy đủ. Nó dẫn đến lỗi (trong Mac), vì nó thiếu dấu gạch chéo đầu tiên tại /Users/.... Để giải quyết nó, tôi đã thêm dấu gạch chéo hàng đầu theo cách thủ công, trong trường hợp ai đó gặp phải vấn đề tương tự ...
J0ANMM

23

Giả sử joinkhông được thiết kế theo cách đó (như ATOzTOA đã chỉ ra) và chỉ cần hai tham số, bạn vẫn có thể sử dụng tích hợp sẵn reduce:

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

Đầu ra tương tự như:

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

Chỉ vì lý do đầy đủ và giáo dục (và cho các tình huống khác *không hoạt động).

Gợi ý cho Python 3

reduceđã được chuyển sang functoolsmô-đun.


2
Trong Python 3 reduceđã được chuyển sang functoolsmô-đun trong trường hợp có ai khác đang tìm kiếm nó như tôi.
Adam Badura

Cảm ơn bạn đã gợi ý, tôi sẽ điều chỉnh câu trả lời của mình.
Thorsten Kranz

3
tiếc rằng python ngày càng rời xa phong cách chức năng thay vì ôm lấy nó và mở ra. chuyển reducesang một mô-đun là một tuyên bố.
SHernandez

Ngay cả trong 2,7 một lonfrom functools import reduce
duhaime

14

Tôi đã vấp phải tình huống mà danh sách có thể trống. Trong trường hợp đó:

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

Lưu ý đối số đầu tiên, đối số này sẽ không làm thay đổi kết quả.


8

Nó chỉ là phương pháp. Bạn không thiếu bất cứ thứ gì. Các tài liệu chính thức cho thấy rằng bạn có thể sử dụng danh sách giải nén để cung cấp nhiều con đường:

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

Lưu ý *sintead của chỉ strong os.path.join(*s). Sử dụng dấu hoa thị sẽ kích hoạt việc giải nén danh sách, có nghĩa là mỗi đối số danh sách sẽ được cung cấp cho hàm dưới dạng một đối số riêng biệt.


Better nhìn vào liên kết của bạn một lần nữa ;-)
Thorsten Kranz

@ Greg nó được ưa thích trên SO để sao chép các phần có liên quan vào câu trả lời và không chỉ dán một liên kết, có lẽ vì vậy downvotes
SHernandez

2

Đây cũng có thể được coi là một hoạt động giảm bản đồ đơn giản nếu bạn muốn nghĩ về nó từ góc độ lập trình chức năng.

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

reducelà nội trang trong Python 2.x. Trong Python 3.x, nó đã được chuyển sang itertoolsTuy nhiên, câu trả lời được chấp nhận là tốt hơn.

Điều này đã được trả lời bên dưới nhưng trả lời nếu bạn có một danh sách các mục cần được tham gia.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.