Pythonic方式将单数值/类列表参数转为列表(等效numpy.atleast_1d)
哈哈,这个需求太常见了!我来给你几个Pythonic的解决方案,完美适配你的场景:
核心思路
你需要先区分两种输入:单个数值(int/float这类不可迭代的) 和 类列表的可迭代结构(比如list、tuple、range等),然后分别处理——把单个数值包装成单元素列表,类列表结构直接转成list保留原有元素。
方法一:通用可迭代判断(推荐)
我们可以用collections.abc.Iterable来识别可迭代对象,但要特意排除字符串(毕竟没人想把单个字符串拆成字符列表来处理对吧?)。
from collections.abc import Iterable def foo(a): # 是可迭代对象且不是字符串?转成list;否则包装成单元素列表 if isinstance(a, Iterable) and not isinstance(a, str): a = list(a) else: a = [a] a.append(5) return a
测试效果:
- 传入单个整数:
foo(3)→[3, 5] - 传入元组:
foo((1,2,3))→[1, 2, 3, 5] - 传入浮点数:
foo(2.718)→[2.718, 5] - 传入单个字符串:
foo("hello")→["hello", 5](不会拆成字符列表)
方法二:更紧凑的三元表达式写法
如果喜欢简洁的代码,上面的判断可以压缩成一行三元表达式:
from collections.abc import Iterable def foo(a): a = list(a) if isinstance(a, Iterable) and not isinstance(a, str) else [a] a.append(5) return a
方法三:严格限定数值类型
如果你只想允许int/float作为单个参数,拒绝其他非类列表的可迭代对象(比如set),可以直接判断类型:
def foo(a): # 是int或float?包装成列表;否则转成list if isinstance(a, (int, float)) and not isinstance(a, bool): a = [a] else: a = list(a) a.append(5) return a
注意:因为
bool是int的子类,isinstance(True, int)会返回True,所以这里加上not isinstance(a, bool)来排除布尔值,如果你不需要这个逻辑可以去掉。
为什么你的原方法会踩坑?
- 直接用
list(a)处理单个数值:比如list(3)会触发TypeError,因为int不是可迭代对象,没法直接转成list。 - 直接用
[a]处理类列表:比如[(1,2,3)]会生成嵌套列表[(1,2,3), 5],完全不符合你的需求。
所以核心就是先做类型判断,区分两种输入再分别处理~
内容的提问来源于stack exchange,提问作者LSchueler
相关产品推荐
相关产品推荐

