编辑: 我坚持使用python 2.7.5 ......
另一个编辑: 澄清变更需要在模板中,而不是处理字典的代码。
我使用字符串格式化程序从模板构建路径。
我知道我可以这样做:
currentUser = {'first': "Monty", 'last': "Python"}
template = '/usr/{user[last]}/{user[first]}' # will come from a config file
template.format(user=currentUser)
# Result: '/usr/Python/Monty'
但是在
的情况下currentUser = {'first': "Raymond", 'last': "Luxury-Yacht"}
有没有办法按-
拆分并使用索引?
# something like:
template = '/usr/{user[last].split(-)[0]/{user[first]}' # will come from a config file
template.format(user=currentUser)
# Result: '/usr/Luxury/Raymond'
决定选择:
必须来自模板字符串;如果当前的迷你语言无法实现这一点,我将不得不编写一个自定义格式化程序。
免责声明:我知道,这个例子有点做作,不实用。我实际上正在处理一个数据库,其中两个关键信息位存储在一个字段中,由下划线连接-_-。我知道我可以在从数据库中提取数据之后对数据进行后处理,但是由于每个项目的这个字段的约定不同,我甚至不能假设拆分操作是有效的(某些值在某些上)项目不会有下划线问题)。我希望能够为用户提供模板"语言"而不是围绕每个约定编写解决方案。所以每个项目本身都可以确定如何提取数据,适应他们选择的任何命名约定,并相应地配置他们的模板。TL / DR:我没有找到修复输入数据的解决方案 - 我正在探索使用Python的字符串格式迷你语言分割字符串的可能性/强>
答案 0 :(得分:1)
您可以使用词典理解:
currentUser = {'first': "Raymond", 'last': "Luxury-Yacht"}
template = '/usr/{user[last]}/{user[first]}'
template.format(user={a:b.split('-')[0] if '-' in b else b for a, b in currentUser.items()})
输出:
'/usr/Luxury/Raymond'
这也适用于您的第一个示例:
currentUser = {'first': "Monty", 'last': "Python"}
template = '/usr/{user[last]}/{user[first]}'
template.format(user={a:b.split('-')[0] if '-' in b else b for a, b in currentUser.items()})
输出:
'/usr/Python/Monty'
作为旁注,在格式化中使用解包(**
)以删除字符串本身中的__getitem__
调用更为Pythonic:
currentUser = {'first': "Raymond", 'last': "Luxury-Yacht"}
template = '/usr/{last}/{first}'.format(**{a:b.split('-')[0] if '-' in b else b for a, b in currentUser.items()})
答案 1 :(得分:1)
如果您对Python 3.6开放,则可以使用f-strings:
users = [{'first': "Raymond", 'last': "Luxury-Yacht"},
{'first': "Monty", 'last': "Python"}]
sep = '-'
for user in users:
path = f"/usr/{user['last'].split(sep)[0]}/{user['first'].split(sep)[0]}"
print(path)
/usr/Luxury/Raymond
/usr/Python/Monty
但是,如果你想在Python 2中坚持你的dict样式格式,你可以使用当前模板和一个小的包装类来清理字典值:
class Wrapper(object):
__slots__ = ('sep', 'dct')
def __init__(self, dct, sep='-'):
self.sep = sep
self.dct = dct
def __getitem__(self, key):
return self.dct[key].split(self.sep)[0]
template = '/usr/{user[last]}/{user[first]}'
for usr in map(Wrapper, users):
path = template.format(user=usr)
print(path)
/usr/Luxury/Raymond
/usr/Python/Monty