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

int*_*tar 215 python types list

在python中,测试变量是否包含列表或元组的最佳方法是什么?(即一个集合)

像这里建议的那样是邪恶吗?http://www.canonical.org/~kragen/isinstance/

更新:我想要将列表与字符串区分开来的最常见原因是当我有一些无限深度的嵌套树/数据结构列表中的字符串列表等列表时,我正在使用递归算法进行探索,我需要知道我何时击中"叶子"节点.

wal*_*l-e 529

if type(x) is list:
    print 'a list'
elif type(x) is tuple:
    print 'a tuple'
else:
    print 'neither a tuple or a list'
Run Code Online (Sandbox Code Playgroud)

  • `[list,tuple]中的`type(x)`更短. (46认同)
  • 在Python 2.7.5中:`type([])是list`返回'True` (3认同)

jcd*_*yer 94

isinstance如果需要,请继续使用.它有点邪恶,因为它排除了您可能实际需要的自定义序列,迭代器和其他内容.但是,如果某人(例如)传递了一个字符串,有时您需要采取不同的行为.我的偏好是明确检查strunicode喜欢这样:

import types
isinstance(var, types.StringTypes)
Run Code Online (Sandbox Code Playgroud)

NB不要搞错types.StringTypetypes.StringTypes.后者包含strunicode对象.

types模块被许多人认为是过时的,只是直接检查对象的类型,所以如果你不想使用上面的,你可以选择明确地检查strunicode,如下所示:

isinstance(var, (str, unicode)):
Run Code Online (Sandbox Code Playgroud)

编辑:

更好的是:

isinstance(var, basestring)
Run Code Online (Sandbox Code Playgroud)

结束编辑

在其中任何一个之后,你可以回归到表现得好像你正在获得一个正常的序列,让非序列引发适当的异常.

看到关于类型检查的"邪恶"并不是你可能想要对某种类型的对象采取不同的行为,这就是你人为地限制你的函数做出正确的事情,否则它会做出正确的事情.如果您的最终回退未经过类型检查,则会删除此限制.应该注意的是,过多的类型检查是代码气味,表明您可能想要进行一些重构,但这并不一定意味着您应该从getgo中避免它.

  • 类型模块有点像历史文物.正如http://docs.python.org/dev/library/types.html#module-types中提到的,如果你真的必须检查`str`类型,你应该直接使用它,而不是使用`types.StringType`这只是它的别名.但我不认为这个答案会回答问题,因为那是关于"收藏品"的问题.除非你使用一个足够新的python来使用`abc`模块,否则你可以使用`isinstance`来检查,即便如此,我也建议尽可能避免检查. (2认同)

Sco*_*ths 38

使用没有任何问题,isinstance只要它不是多余的.如果变量应该只是一个列表/元组,那么记录接口并只使用它.否则检查是完全合理的:

if isinstance(a, collections.Iterable):
    # use as a container
else:
    # not a container!
Run Code Online (Sandbox Code Playgroud)

这种类型的检查确实有一些很好的用例,例如使用标准字符串startswith/endswith方法(虽然准确这些是在CPython中用C实现的,使用显式检查来查看它是否是一个元组 - 有多种方法解决这个问题,如你链接到的文章所述).

显式检查通常比尝试将对象用作容器并处理异常更好 - 这可能导致代码部分或不必要地运行的各种问题.

  • 这是检查变量是否可迭代的好方法.但是,它可能不适用于此问题.请注意,字符串也是可迭代的,可能会产生误报. (14认同)

Ign*_*ams 14

将参数记录为需要成为序列,并将其用作序列.不要检查类型.


use*_*881 11

怎么样:hasattr(a, "__iter__")

它告诉返回的对象是否可以作为生成器迭代.默认情况下,元组和列表可以,但不能是字符串类型.

  • 字符串的结果也是True(至少在Python 3上). (8认同)
  • 这是错误的答案。由于类型 'str' 也有方法 '__iter__'。@SzieberthAdam 是对的。'set' 类型也是可迭代的,但不可排序。 (3认同)

j4h*_*gir 11

我推荐唯一的Pythonic方式:

if isinstance(x, (list, tuple))): pass

Run Code Online (Sandbox Code Playgroud)

  • 在最初的问题发布 13 年后,这个答案是在 Python3 中实现这一目标的最直接的方法。 (2认同)

小智 10

在Python 2.8 type(list) is list返回时,false
我建议以这种可怕的方式比较类型:

if type(a) == type([]) :
  print "variable a is a list"
Run Code Online (Sandbox Code Playgroud)

(至少在我的系统上,在Mac OS X Yosemite上使用anaconda)

  • 你的意思是Python 2.7.8吗?https://www.python.org/dev/peps/pep-0404/#official-pronouncement (4认同)
  • `type(list) is list` 返回 `False`,因为 `type(list)` 是 `type`,而不是 `list`。`type(list()) is list` 或列表的任何其他 *实例* 将返回 `True`。 (2认同)

Wim*_*Wim 8

Python使用"Duck typing",即如果变量kwaks像鸭子一样,它必须是鸭子.在您的情况下,您可能希望它是可迭代的,或者您想要访问某个索引处的项目.你应该这样做:即使用块中for var:或块var[idx]内的对象try,如果你得到一个例外它不是一个鸭子......

  • 这个问题是如果`var`是一个字符串迭代将发生可能意外的结果. (7认同)

小智 6

>>> l = []
>>> l.__class__.__name__ in ('list', 'tuple')
True
Run Code Online (Sandbox Code Playgroud)


小智 5

确定变量是列表还是元组或通常检查变量类型的另一种简单方法是:

def islist(obj):
    if ("list" in str(type(obj))):
        return True
    else:
        return False
Run Code Online (Sandbox Code Playgroud)