列表中的 Python os.path.join()

我能做到

>>> 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']

我错过了什么?

165893 次浏览

问题是,os.path.join不接受 list作为参数,它必须是独立的参数。

打开清单转换为 join所需的单独参数(对于 record: list 来自使用 split的字符串)、 使用 *或‘ splat’操作符,因此:

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

只是方法问题。你什么都没错过。正式文件显示,您可以使用 list 解包来提供几个路径:

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

请注意,在 os.path.join(*s)中使用的是 *s,而不仅仅是 s。使用星号将触发对列表的解压缩,这意味着每个列表参数将作为单独的参数提供给函数。

假设 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模块。

我无意中发现这个列表可能是空的。在这种情况下:

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

注意第一个参数,它不会改变结果。

如果您希望从函数式编程的角度来考虑这个问题,那么也可以将其视为一个简单的 map reduce 操作。

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,但是接受的答案更好。

这个问题已经在下面回答了,但是如果你有一个需要加入的项目的列表的话,这个问题就可以回答了。