用于解压缩带有大括号抑制的列表的 f-string 语法
f-string syntax for unpacking a list with brace suppression
我一直在使用新的 f 字符串格式检查我的一些字符串格式选项。我经常需要解包列表和其他长度未知的迭代。目前我使用以下...
>>> a = [1, 'a', 3, 'b']
>>> ("unpack a list: " + " {} "*len(a)).format(*a)
'unpack a list: 1 a 3 b '
这虽然有点麻烦,但可以使用 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 字符串
这使外观和语法变得更好,因为评估显然是从左到右进行的。然而,这仍然留下了封闭的大括号:
>>> 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-string 提供的新功能,而不是恢复到 python 版本之外,这些版本早于我目前熟悉的版本。我开始怀疑 f'strings' 没有完全涵盖其 .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)
使用尾随逗号解包。
因为任何有效的 Python 表达式都是 allowed 在 f 字符串的大括号内,您可以简单地使用 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'
简单的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'
我不认为这是 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
在解压后的列表后面加一个逗号即可。
a = [1, 2, 3]
print(f"Unpacked list: {*a,}")
# Unpacked list: (1, 2, 3)
此语法有更长的解释 。
我不久前做了这个,包括逗号牛津风格。
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
我一直在使用新的 f 字符串格式检查我的一些字符串格式选项。我经常需要解包列表和其他长度未知的迭代。目前我使用以下...
>>> a = [1, 'a', 3, 'b']
>>> ("unpack a list: " + " {} "*len(a)).format(*a)
'unpack a list: 1 a 3 b '
这虽然有点麻烦,但可以使用 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 字符串
这使外观和语法变得更好,因为评估显然是从左到右进行的。然而,这仍然留下了封闭的大括号:
>>> 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-string 提供的新功能,而不是恢复到 python 版本之外,这些版本早于我目前熟悉的版本。我开始怀疑 f'strings' 没有完全涵盖其 .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)
使用尾随逗号解包。
因为任何有效的 Python 表达式都是 allowed 在 f 字符串的大括号内,您可以简单地使用 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'
简单的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'
我不认为这是 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
在解压后的列表后面加一个逗号即可。
a = [1, 2, 3]
print(f"Unpacked list: {*a,}")
# Unpacked list: (1, 2, 3)
此语法有更长的解释
我不久前做了这个,包括逗号牛津风格。
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