Это легко сделать с помощью рекурсивной функции. Давайте посмотрим на пример реализации. Здесь мы отобразим все строки в данном контейнере для данной функции, мы также будем использовать Понимания списка и Понимания словаря для имитации исходной вложенной структуры. Кроме того, встроенная функция isinstance используется для проверки типа заданного параметра:
def convert(func, d):
if (isinstance(d, str)):
return func(d)
elif (isinstance(d, dict)):
return {key : convert(func, d[key]) for key in d}
elif (isinstance(d, list)):
return [convert(func, val) for val in d]
Применяется func
к каждой строке в контейнере. Проверьте это с помощью своего примера словаря и os.path.expanduser :
x = dict(
dir = dict(
wd = '~/Desktop/WD',
pymodule = [
'~/Documents/PythonModule',
'/Users/Username/Documents/PythonModule2'
],
album = '~/Desktop/Album'
),
file = dict(
XML = '~/Downloads/data.xml',
CSV = '~/Downloads/data.csv'
)
)
import os
x = convert(os.path.expanduser, x)
print(x)
И, конечно же, вы получите желаемый результат:
{'dir': {'wd': '/home/runner/Desktop/WD', 'pymodule': ['/home/runner/Documents/PythonModule', '/Users/Username/Documents/PythonModule2'], 'album': '/home/runner/Desktop/Album'}, 'file': {'XML': '/home/runner/Downloads/data.xml', 'CSV': '/home/runner/Downloads/data.csv'}}