为何Python格式化字符串传列表报错,传元组却正常?
为什么格式化字符串传入列表失败,但转成元组就正常?
为什么向以下格式化方法传入列表会失败,但将同一列表转为元组传入却能正常运行?经测试,该元组并未继承Python的原子数值类型(我认为也未继承复数类型),因此我对解释器的反馈感到困惑:为何它能将元组视为包含格式化值的对象,却不能同等处理列表?
测试代码
#!/usr/bin/env python3 import math from multiprocessing import Pool def func(x): return math.sin(x) if __name__ == "__main__": with Pool(5) as p: x = p.map(func, range(1, 4)) x_tuple = tuple(x) try: print(", ".join([r"%2f"] * len(x)) % x) print(f"Print with list succeeded") except Exception as e: print(f"传入列表打印失败:{e}") try: print(", ".join([r"%2f"] * len(x_tuple)) % x_tuple) print(f"传入元组打印成功") except: print(f"传入元组打印失败:{e}") print(f"{isinstance(x, float) = }") print(f"{isinstance(x, int) = }")
运行输出
传入列表打印失败:必须是实数,而非列表 0.841471, 0.909297, 0.141120 传入元组打印成功 isinstance(x, float) = False isinstance(x, int) = False
原因解释
这是Python旧式字符串格式化操作符%的规则决定的:
- 当
%右侧是元组时,它会被自动拆分成多个独立参数,一一匹配格式化字符串中的每个占位符(这里的三个%2f),所以能正常格式化每个数值。 - 当
%右侧是列表时,它会被当作一个单独的整体参数,只会尝试匹配第一个%2f占位符,但%2f要求传入实数类型,列表不符合这个要求,因此抛出类型错误。
如果想用列表实现同样效果,可以用*操作符解包列表,把它拆分成多个参数传入:
print(", ".join([r"%2f"] * len(x)) % (*x,))
内容的提问来源于stack exchange,提问作者Anil
相关产品推荐
相关产品推荐

