用于解压缩具有大括号抑制的列表的f-string语法

时间:2017-03-13 04:16:42

标签: python python-3.x string-formatting python-3.6 f-string

我一直在使用新的f-string格式检查一些字符串格式选项。我经常需要解压缩列表和其他未知长度的迭代。目前我使用以下内容......

>>> a = [1, 'a', 3, 'b']
>>> ("unpack a list: " + " {} "*len(a)).format(*a)
'unpack a list:  1  a  3  b '

这虽然有点麻烦,但使用3.6之前的格式表示法。 考虑到运行时字符串连接,新的f-string格式选项很有意思。这是我遇到问题的{}数量的复制。在我之前的例子中,我只是创建了必要的结构并在.format()部分中解压缩。

尝试这样做产生了一个有效的变体,但是,我不能将两个花括号放在一起,或者它不能解压缩...

(1)

>>> 'unpack a list'  f' {{*a}}'
'unpack a list {*a}'

按下,我在内部{}对周围插入了一个空格。这是一个适度的改进,但是开始和结束{,}现在。

(2)

>>> 'unpack a list'  f' { {*a} }'
"unpack a list {1, 3, 'a', 'b'}"

将变体拼接成一个封闭的f-string使外观和语法更好,因为评估显然是从左到右。但是,这仍然留下了封闭的大括号。

(3)

>>> f'unpack a list { {*a} }'
"unpack a list {1, 3, 'a', 'b'}"

也许,我正在过度思考整个过程并希望能够进行某种形式的自动拆包。这只是产生了列表表示,大括号被[]替换 (4)

>>> f'unpack a list {a}'
"unpack a list [1, 'a', 3, 'b']"

在上面的变体(3)中抑制大括号需要什么,或者我是否已经辞职继续使用我习惯的.format()选项。我想保持简单并使用f-string提供的新功能,而不是回溯到我目前所熟悉的python版本之外。我开始怀疑f'strings'不能完全覆盖其.format()兄弟所提供的内容。我现在就把它留在那里,因为我甚至没有冒险进入转义编码和无法在f字符串中使用\。我已经阅读了PEP并广泛搜索,但是,我觉得我错过了显而易见的或我希望的目前无法实现的目标。

几小时后编辑

我确实找到了这个变体,它可以用于我需要的一些情况

f'unpack a list: {str(a)[1:-2]}'
"unpack a list: 1, 'a', 3, 'b"

但切片只不过是方便,仍然会在结果周围留下字符串引号。

5 个答案:

答案 0 :(得分:12)

由于f字符串中大括号内的任何有效Python表达式都是allowed,因此您只需使用str.join()即可生成所需的结果:

>>> a = [1, 'a', 3, 'b']
>>> f'unpack a list: {" ".join(str(x) for x in a)}'
'unpack a list: 1 a 3 b'

你当然也可以写一个辅助函数,如果你的真实世界用例使上面的内容比你更加冗长:

def unpack(s):
    return " ".join(map(str, s))  # map(), just for kicks

>>> f'unpack a list: {unpack(a)}'
'unpack a list: 1 a 3 b'

答案 1 :(得分:11)

只需在解压缩列表后添加一个逗号即可。

a = [1, 2, 3]
print(f"Unpacked list: {*a,}")

对此语法in this thread有更长的解释。

答案 2 :(得分:0)

简单的Python可能更清晰:

>>>  'unpack a list: ' + ' '.join(str(x) for x in a)
'unpack a list: 1 a 3 b'

切片:

>>> 'unpack a list: ' + ' '.join([str(x) for x in a][1:3])
'unpack a list: a 3'

答案 3 :(得分:0)

我不认为这是使用f-Strings的方式。充其量我可以想象准备一个与print()兼容的元组,例如:

mixed = [1, "list_string", 2]
number = 23
answer = 46

info = 'Content:', *mixed, f'{number} {answer}'
print(*info)  # default sep=' '

输出

Content: 1 list_string 2 23 46

答案 4 :(得分:0)

我做过一段时间,包括了牛津风格的逗号。

def unpack_list(lst):  # Oxford comma
    if not isinstance(lst, str):
        lst = [str(item) for item in lst]
    if len(lst) == 0:
        return
    if len(lst) == 1:
        return ", ".join(lst)
    if len(lst) == 2:
        return ", and ".join(lst) 
    else:
        first_part = lst[:-1]
        last_part = lst[-1]
        return ", ".join(first_part) + ", and " + last_part