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.Wan

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модуль на випадок, якщо хтось ще шукав його, як і я.
Адам Бадура,

Дякую за підказку, я скорегую свою відповідь.
Торстен Кранц,

3
Шкода, що пітон все більше віддаляється від функціонального стилю, замість того, щоб його обійняти і відкрити. перехід reduceдо модуля - це твердження.
Шернандес

Навіть у 2.7 можнаfrom functools import reduce
може,

14

Я натрапив на ситуацію, коли список може бути порожнім. В такому разі:

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

Зверніть увагу на перший аргумент, який не змінить результат.


8

Це просто метод. Ви нічого не пропускаєте. В офіційній документації показує , що ви можете використовувати список розпакування , щоб поставити кілька шляхів:

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

Зверніть увагу на *sте, що просто sв os.path.join(*s). Використання зірочки спричинить розпакування списку, що означає, що кожен аргумент списку буде надісланий функції як окремий аргумент.


Краще ще раз перегляньте своє посилання ;-)
Торстен Кранц,

@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Однак прийнята відповідь є кращою.

На це дано відповідь нижче, але відповідь, якщо у вас є список елементів, які потрібно об’єднати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.