测试变量是否为列表或元组

316 投票
16 回答
402710 浏览
提问于 2025-04-15 18:47

在Python中,怎么判断一个变量是不是列表或元组呢?也就是判断它是不是一个集合。

有人说使用isinstance()这个方法很糟糕,这是真的吗? http://www.canonical.org/~kragen/isinstance/

更新:我想区分列表和字符串的最常见原因是,当我有一个无限深的嵌套树结构,比如列表里面还有列表,里面又有字符串等,我用递归算法在探索这个结构时,需要知道我什么时候到达了“叶子”节点。

16 个回答

43

使用 isinstance 这个方法是没问题的,只要它不是多余的。如果一个变量应该只是一种列表或元组,那就把这个要求写清楚,然后就按照这个要求来用它。否则,进行检查也是很合理的:

if isinstance(a, collections.abc.Iterable):
    # use as a container
else:
    # not a container!

这种类型的检查在一些情况下是有好处的,比如在标准字符串的 startswithendswith 方法中(不过要准确说,这些方法在 CPython 中是用 C 语言实现的,里面会明确检查是不是元组 - 解决这个问题的方法有很多,就像你提到的文章里说的那样)。

明确的检查通常比试图把对象当作容器来用,然后处理异常要好得多 - 这样做可能会导致代码部分运行或者不必要的错误。

662

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这种情况可能是因为我们没有正确理解某些概念或者使用了不合适的方法。

例如,假设你在写一个程序,结果发现它没有按照预期工作。这时候,你需要仔细检查你的代码,看看是不是哪里出错了。可能是你用了错误的变量名,或者在错误的地方加了代码。

另外,编程中还有很多工具和资源可以帮助你解决问题,比如在线论坛、文档和教程。通过这些资源,你可以找到别人遇到的类似问题和解决方案。

总之,遇到问题时不要着急,慢慢分析,查找资料,通常都能找到解决办法。

if type(x) is list:
    print 'a list'
elif type(x) is tuple:
    print 'a tuple'
else:
    print 'neither a tuple or a list'
125

如果你需要的话,可以使用 isinstance。不过它有点“邪恶”,因为它会排除一些自定义的序列、迭代器和其他你可能需要的东西。不过,有时候如果有人传了一个字符串,你可能需要采取不同的处理方式。在这种情况下,我更倾向于明确检查一下是不是 strunicode,像这样:

import types
isinstance(var, types.StringTypes)

注意:不要把 types.StringTypetypes.StringTypes搞混了。后者包含了 strunicode 对象。

很多人认为 types 模块已经过时了,直接检查对象的类型就可以了。所以如果你不想用上面的方法,也可以直接检查 strunicode,像这样:

isinstance(var, (str, unicode)):

编辑:

更好的方法是:

isinstance(var, basestring)

结束编辑

在这两种方法之后,你可以继续像处理普通序列那样处理,让非序列的情况抛出适当的异常。

这里所说的“邪恶”并不是说你想对某种类型的对象采取不同的处理方式,而是你人为地限制了你的函数,无法正确处理那些意外的对象类型,而这些类型本来是可以正确处理的。如果你有一个最终的后备方案,而不进行类型检查,那么你就去掉了这种限制。需要注意的是,过多的类型检查可能是代码质量不佳的表现,说明你可能需要重构一下代码,但这并不意味着你一开始就应该完全避免类型检查。

撰写回答