Python os.path.join () ในรายการ


97

ที่ฉันสามารถทำได้

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

แต่เมื่อฉันทำ

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

ฉันพลาดอะไรไปที่นี่?

คำตอบ:


197

ปัญหาคือos.path.joinไม่ได้ใช้listเป็นอาร์กิวเมนต์ แต่จะต้องมีการโต้แย้งแยกกัน

นี่คือจุดที่*ตัวดำเนินการ 'splat' เข้ามามีบทบาท ...

ที่ฉันสามารถทำได้

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

10
บริบทเพิ่มเติมสำหรับ splat: docs.python.org/2/tutorial/…
A.

3
โปรดทราบว่าฉันพยายามใช้สิ่งนี้เพื่อลบส่วนสุดท้ายของเส้นทางแบบเต็ม ส่งผลให้เกิดข้อผิดพลาด (ใน Mac) เนื่องจากไม่มีเครื่องหมายทับแรกที่/Users/.... เพื่อแก้ปัญหานี้ฉันได้เพิ่มเครื่องหมายทับด้วยตนเองในกรณีที่มีคนประสบปัญหาเดียวกัน ...
J0ANMM

23

สมมติjoinว่าไม่ได้ออกแบบมาอย่างนั้น (ซึ่งเป็นไปตามที่ ATOzTOA ชี้ให้เห็น) และใช้พารามิเตอร์เพียงสองตัวคุณยังสามารถใช้บิวท์อินได้reduce:

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

ผลลัพธ์เดียวกันเช่น:

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

เพียงเพื่อความสมบูรณ์และเหตุผลทางการศึกษา (และสำหรับสถานการณ์อื่น ๆ ที่*ไม่ได้ผล)

คำแนะนำสำหรับ Python 3

reduceถูกย้ายไปที่functoolsโมดูล


2
ใน Python 3 reduceถูกย้ายไปยังfunctoolsโมดูลในกรณีที่คนอื่นกำลังมองหามันเหมือนฉัน
Adam Badura

ขอบคุณสำหรับคำใบ้ฉันจะปรับคำตอบ
Thorsten Kranz

3
น่าเสียดายที่งูหลามเดินห่างจากรูปแบบการใช้งานมากขึ้นเรื่อย ๆ แทนที่จะกอดมันและเปิดขึ้น การย้ายreduceออกไปยังโมดูลเป็นคำสั่ง
SHernandez

แม้ใน 2.7 หนึ่งกระป๋องfrom functools import reduce
duhaime

14

ฉันสะดุดกับสถานการณ์ที่รายการอาจว่างเปล่า ในกรณีนั้น:

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

สังเกตอาร์กิวเมนต์แรกซึ่งจะไม่เปลี่ยนแปลงผลลัพธ์


8

มันเป็นเพียงวิธีการ คุณไม่ได้ขาดอะไรเลย เอกสารอย่างเป็นทางการแสดงให้เห็นว่าคุณสามารถใช้รายการเปิดออกเพื่อจัดหาหลายเส้นทาง:

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

หมายเหตุ*sIntead เพียงในs os.path.join(*s)การใช้เครื่องหมายดอกจันจะทริกเกอร์การคลายรายการซึ่งหมายความว่าอาร์กิวเมนต์รายการแต่ละรายการจะถูกส่งไปยังฟังก์ชันเป็นอาร์กิวเมนต์แยกต่างหาก


ดูลิงค์ของคุณอีกครั้งดีกว่า ;-)
Thorsten Kranz

@Greg เป็นที่ต้องการให้ SO คัดลอกส่วนที่เกี่ยวข้องลงในคำตอบและไม่ใช่แค่วางลิงก์เท่านั้นบางทีอาจจะมีการ
โหวตดาวน์

2

นอกจากนี้ยังสามารถคิดว่าเป็นแผนที่เรียบง่ายลดการดำเนินการหากคุณต้องการคิดจากมุมมองการเขียนโปรแกรมเชิงฟังก์ชัน

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

reduceถูกสร้างขึ้นใน Python 2.x. ใน Python 3.x ถูกย้ายไปที่itertoolsอย่างไรก็ตามคำตอบที่ยอมรับนั้นดีกว่า

คำตอบนี้ได้รับการตอบกลับด้านล่าง แต่หากคุณมีรายการที่จะต้องเข้าร่วม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.