web-dev-qa-db-fra.com

Python os.path.join () sur une liste

Je peux faire

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

Mais quand je fais

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

Qu'est-ce que j'oublie ici?

73
ATOzTOA

Le problème est, os.path.join _ ne prend pas list comme argument, il doit s'agir d'arguments séparés.

C'est ici que *, l'opérateur 'splat' entre en jeu ...

Je peux faire

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

En supposant que join n’ait pas été conçu de cette façon (comme c’est le cas, comme ATOzTOA l’a souligné), et qu’il ne prend que deux paramètres, vous pouvez toujours utiliser le paramètre intégré reduce:

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

Même résultat comme:

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

Juste pour des raisons d’intégralité et d’éducation (et pour d’autres situations où * _ ne fonctionne pas).

Indice pour Python Pour Python 3, reduce a été déplacé vers le module functools. .

19
Thorsten Kranz

Je suis tombé sur la situation où la liste pourrait être vide. Dans ce cas:

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

Notez le premier argument, qui ne modifiera pas le résultat.

8
Sebastian Mach

C'est juste la méthode. Vous ne manquez rien. Le documentation officielle montre que vous pouvez utiliser la décompression de liste pour fournir plusieurs chemins:

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

Notez le *s Au lieu de s dans os.path.join(*s). L'utilisation de l'astérisque déclenchera la décompression de la liste, ce qui signifie que chaque argument de liste sera fourni à la fonction en tant qu'argument séparé.

6
Greg

Cela peut également être considéré comme une simple opération de réduction de carte si vous souhaitez y penser du point de vue de la programmation fonctionnelle.

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

reduce est intégré Python 2.x. Dans Python 3.x, il a été déplacé vers itertools. accepté la réponse est mieux.

Vous trouverez la réponse ci-dessous, mais si vous avez une liste d'éléments à joindre.

0
Nishant