可以使用字符串格式来分割字符串值吗?

时间:2017-11-17 19:39:03

标签: python string split format

编辑: 我坚持使用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'

决定选择:

  • 分割哪个键
  • by what character
  • 使用split
  • 的索引

必须来自模板字符串;如果当前的迷你语言无法实现这一点,我将不得不编写一个自定义格式化程序。

免责声明:我知道,这个例子有点做作,不实用。我实际上正在处理一个数据库,其中两个关键信息位存储在一个字段中,由下划线连接-_-。我知道我可以在从数据库中提取数据之后对数据进行后处理,但是由于每个项目的这个字段的约定不同,我甚至不能假设拆分操作是有效的(某些值在某些上)项目不会有下划线问题)。我希望能够为用户提供模板"语言"而不是围绕每个约定编写解决方案。所以每个项目本身都可以确定如何提取数据,适应他们选择的任何命名约定,并相应地配置他们的模板。

TL / DR:我没有找到修复输入数据的解决方案 - 我正在探索使用Python的字符串格式迷你语言分割字符串的可能性/强>

2 个答案:

答案 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