我有一个字典,其中可能包含任意任意顺序的字符串,字符串列表或最终以字符串结尾的嵌套字典。我想遍历该字典并对每个字符串执行一个操作。
This问题与我要寻找的问题很接近,但是我未能将该解决方案应用于自己的解决方案。
我需要将函数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'
)
)
理想情况下,我想定义一个类,当在普通词典中调用该类时,它将在该词典的每个字符串元素上应用os.path.expanduser()
。
class MyDict:
def __init__(d):
self.d = d
# some operation to apply os.path.expanduser() on each string element of 'd'
我该如何实现?
答案 0 :(得分:2)
这可以通过递归函数轻松完成。让我们看一个示例实现。在这里,我们将给定容器中的所有字符串映射到给定函数,我们还将使用List Comprehensions和Dictionary Comprehensions来模仿原始的嵌套结构。另外,内置的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'}}
答案 1 :(得分:2)
这是一个函数,它使用一个嵌套结构x
作为输入,并返回一个类似的嵌套结构,其中所有字符串都已扩展:
def expand(x):
if isinstance(x, str):
return os.path.expanduser(x)
if isinstance(x, dict):
return { key : expand(x[key]) for key in x }
if isinstance(x, list):
return [ expand(elem) for elem in x ]
return x
例如用
调用expand({1: '~/Hello', 2: ['~/World', '~/foo']})
将返回
{1: '/home/hkoehler/Hello', 2: ['/home/hkoehler/World', '/home/hkoehler/foo']}
答案 2 :(得分:0)
这里有个函数可以做到:
import json
import os
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'
)
)
def func(d):
for key, value in d.items():
if isinstance(value, dict):
func(value)
elif isinstance(value, str):
d[key] = os.path.expanduser(value)
elif isinstance(value, list):
for i, element in enumerate(value):
if isinstance(element, str):
value[i] = os.path.expanduser(element)
func(x)
print(json.dumps(x, indent=4))
输出:
{
"dir": {
"wd": "C:\\Users\\martineau/Desktop/WD",
"pymodule": [
"C:\\Users\\martineau/Documents/PythonModule",
"/Users/Username/Documents/PythonModule2"
],
"album": "C:\\Users\\martineau/Desktop/Album"
},
"file": {
"XML": "C:\\Users\\martineau/Downloads/data.xml",
"CSV": "C:\\Users\\martineau/Downloads/data.csv"
}
}