我一直在使用新的f-string格式检查我的字符串格式选项。我经常需要解包长度未知的列表和其他可迭代对象。目前我使用以下方法...
>>> a = [1, 'a', 3, 'b']
>>> ("unpack a list: " + " {} "*len(a)).format(*a)
'unpack a list: 1 a 3 b '
虽然有点繁琐,但使用 pre-3.6 的 .format 符号可以完成工作。新的 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'}"
2b) 将变量连接成一个f-string
这样做使得代码看起来更好,语法更清晰,因为显然是从左到右进行求值的。但是,这仍然保留了包含花括号:
>>> f'unpack a list { {*a} }'
"unpack a list {1, 3, 'a', 'b'}"
3) 只使用{a}
尝试自动解包
也许我过于考虑整个过程,希望能够自动解包。但这只会得到用方括号[]
代替花括号的列表表示:
>>> f'unpack a list {a}'
"unpack a list [1, 'a', 3, 'b']"
如何抑制上面变体(2)中的花括号,我必须继续使用现有的.format()
方法吗?我想保持简单,使用f字符串提供的新功能,并且不会回退到比我当前熟悉的Python版本更早的版本。我开始怀疑f字符串并没有完全覆盖其.format()
兄弟所提供的所有内容。我现在就说到这里,因为我甚至还没有涉及转义编码和无法在f字符串中使用\的问题。我已阅读PEP并进行了广泛搜索,但我觉得我可能忽略了显而易见的部分,或者我希望的目前不可能实现。
几个小时后编辑:
4) 使用下标手动删除括号:str(a)[1:-2]
我发现这个变体可以用于我需要的一些情况
f'unpack a list: {str(a)[1:-2]}'
"unpack a list: 1, 'a', 3, 'b"
但是切片仅仅是一种方便的方法,结果中仍然保留了字符串引号。
5) 并来自@SenhorLucas的最终解决方案
a = np.arange(10)
print(f"{*a,}")
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
带有尾随逗号的解包。
f"unpack a list: {', '.join([str(x) for x in [*a]])}"
returns'unpack a list: 1, a, 3, b'
- noobninja.format()
方法,而只是为了使常见情况更加简洁并增加功能;总会有需要使用.format()
的情况,包括格式化列表/元组/集合/任意对象或嵌套对象。这并不是回到 pre-3.6 语法的情况;.format()
不打算被弃用以支持 f-strings。不可否认的是,f-string 的文档应该明确说明这一点。同时它也违反了 "做一件事情应该有且只有一种显而易见的方法" 这一原则。 - smci