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

isinstance()是否如这里所建议的那样邪恶?http://www.canonical.org/~kragen/isinstance/

更新:我想要区分列表和字符串的最常见原因是,当我有一些无限深嵌套的字符串列表的列表的列表的树/数据结构时,我正在用递归算法探索,我需要知道什么时候我已经碰到了“叶”节点。


当前回答

另一个简单的方法来确定一个变量是列表还是元组,或者检查变量类型:

def islist(obj):
    if ("list" in str(type(obj))):
        return True
    else:
        return False

其他回答

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

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

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

这种类型的检查确实有一些很好的用例,比如标准字符串startswith / endswith方法(尽管准确地说,这些方法是在CPython中使用显式检查来实现的,以确定它是否是一个元组——解决这个问题的方法不止一种,正如你链接到的文章中提到的那样)。

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

不是最优雅的,但我做到了(对于Python 3):

if hasattr(instance, '__iter__') and not isinstance(instance, (str, bytes)):
    ...

这允许其他可迭代对象(如Django queryset),但不包括字符串和字节串。我通常在接受单个对象ID或对象ID列表的函数中使用这种方法。有时候对象id可以是字符串我不想一个字符一个字符地遍历这些。:)

如果你只需要知道你是否可以对变量使用foo[123]符号,你可以用hasattr(foo, '__getitem__')检查是否存在__getitem__属性(这是python在通过索引访问时调用的属性)。

那么:hasattr(a, "__iter__")呢?

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