清单上的Python os.path.join()

问题:清单上的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']

我在这里想念什么?

I can do

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

But, when I do

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

What am I missing here?


回答 0

问题是,os.path.join不接受listas参数,它必须是单独的参数。

在这里*,“ splat”运算符开始起作用…

我可以

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

The problem is, os.path.join doesn’t take a list as argument, it has to be separate arguments.

This is where *, the ‘splat’ operator comes into play…

I can do

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

回答 1

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

Assuming join wasn’t designed that way (which it is, as ATOzTOA pointed out), and it only took two parameters, you could still use the built-in reduce:

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

Same output like:

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

Just for completeness and educational reasons (and for other situations where * doesn’t work).

Hint for Python 3

reduce was moved to the functools module.


回答 2

我偶然发现列表可能为空的情况。在这种情况下:

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

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

I stumbled over the situation where the list might be empty. In that case:

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

Note the first argument, which will not alter the result.


回答 3

这只是方法。您什么都不会错过。在官方文件显示,你可以用列表拆包提供几条路径:

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

注意in中的*sintead 。使用星号将触发列表的解压缩,这意味着每个列表参数将作为单独的参数提供给函数。sos.path.join(*s)

It’s just the method. You’re not missing anything. The official documentation shows that you can use list unpacking to supply several paths:

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

Note the *s intead of just s in os.path.join(*s). Using the asterisk will trigger the unpacking of the list, which means that each list argument will be supplied to the function as a separate argument.


回答 4

如果您希望从功能编程的角度考虑它,也可以将其视为简单的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但是,公认的答案更好。

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

This can be also thought of as a simple map reduce operation if you would like to think of it from a functional programming perspective.

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

reduce is builtin in Python 2.x. In Python 3.x it has been moved to itertools However the accepted the answer is better.

This has been answered below but answering if you have a list of items that needs to be joined.