在python中,测试变量是否包含列表或元组的最佳方法是什么?(即集合)
是isinstance()
邪恶的建议在这里?http://www.canonical.org/~kragen/isinstance/
更新:我想从字符串中区分列表的最常见原因是当我有一些无限深的嵌套树/字符串列表等列表的数据结构时,我正在使用递归算法进行探索,我需要知道我何时击中“叶子”节点。
在python中,测试变量是否包含列表或元组的最佳方法是什么?(即集合)
是isinstance()
邪恶的建议在这里?http://www.canonical.org/~kragen/isinstance/
更新:我想从字符串中区分列表的最常见原因是当我有一些无限深的嵌套树/字符串列表等列表的数据结构时,我正在使用递归算法进行探索,我需要知道我何时击中“叶子”节点。
Answers:
继续使用,isinstance
如果需要的话。这有点邪恶,因为它不包括自定义序列,迭代器和您可能实际需要的其他东西。但是,有时,例如,有人传递字符串时,您需要采取不同的行为。我的偏好是明确检查str
或unicode
类似:
import types
isinstance(var, types.StringTypes)
NB千万不要误会types.StringType
了types.StringTypes
。后者包含str
和unicode
对象。
types
许多人认为该模块已过时,只支持直接检查对象的类型,因此,如果您不想使用以上内容,则可以替代地显式检查str
and unicode
,例如:
isinstance(var, (str, unicode)):
编辑:
更好的是:
isinstance(var, basestring)
结束编辑
在这两种情况中的任何一种之后,您都可以回到正常的序列状态,让非序列引发适当的异常。
看到关于类型检查的“邪恶”之处不是您可能不想对某种特定类型的对象表现出不同的行为,而是您人为地限制了函数使用意外的对象类型来执行正确的操作,否则它们将执行正确的操作。如果您有未经过类型检查的最终后备,则可以删除此限制。应该注意的是,过多的类型检查是一种代码异味,表明您可能想要进行一些重构,但这并不一定意味着您应该避免从getgo中进行此操作。
str
类型,则应直接使用该类型,而不是types.StringType
仅使用它的别名。但是我认为这个答案不能回答所提出的问题,因为那是关于“集合”的。除非您使用足够新的python以拥有abc
不是您可以isinstance
用来检查的模块,否则即使如此,我还是建议您尽可能避免进行检查。
assert isinstance(u'abc', str) == False
。我同意最好直接检查类型,而不是使用types
模块,但types.StringTypes
这样做str
却不行:它为str
and unicode
对象返回True 。我将编辑我的回复,以提供再次检查的替代方法。
isinstance
邪恶的吗?” 我给出了一个反例,其中(1)是对Evil的非邪恶用途isinstance
,因为具有后备意味着它不会破坏鸭嘴兽,并且(2)是人们想要检查是否有非常普遍动机的良好解决方案某物是一个list
或tuple
(即从字符串中消除它们的歧义)。
class Foo(str): pass
想做什么?
if type(x) is list:
print 'a list'
elif type(x) is tuple:
print 'a tuple'
else:
print 'neither a tuple or a list'
type([]) is list
返回True
type(x) in [list,tuple]
更短。
没有什么错误使用isinstance
,只要它不是多余的。如果变量仅应是列表/元组,则记录该接口并按原样使用它。否则,检查是完全合理的:
if isinstance(a, collections.Iterable):
# use as a container
else:
# not a container!
这种类型的检查确实有一些很好的使用情况,如与标准字符串startswith / 的endsWith方法(虽然是准确的,这些都是使用一个明确的检查,看它是否是一个元组用C语言实现的CPython的-有不止一种方法如您所链接的文章所述,以解决此问题)。
显式检查通常比尝试将对象用作容器并处理异常要好-这可能会导致部分或不必要地运行代码的各种问题。
set
对象也是一个迭代,这意味着,虽然你肯定可以从弹出它的元素,但它并不能保证一定的顺序,这是一定的算法非常危险的事情。在元素的顺序确实很重要的情况下,使用此代码段的算法可能会在不同的运行中产生不同的结果!
将自变量需要记录为序列,并将其用作序列。不要检查类型。
如何:hasattr(a, "__iter__")
?
它告诉返回的对象是否可以作为生成器进行迭代。默认情况下,元组和列表可以,但字符串类型不能。
__iter__
。
__iter__
由于某种原因,任何自定义类型都可能具有...
在Python 2.8 type(list) is list
返回上,false
我建议以这种可怕的方式比较类型:
if type(a) == type([]) :
print "variable a is a list"
(至少在我的系统上,在Mac OS X Yosemite上使用anaconda)
type(list) is list
回报False
,因为type(list)
是type
,不list
。 type(list()) is list
或与列表的任何其他实例一起返回True
。
Python使用“鸭子类型”,即,如果变量像鸭子一样醒来,则它一定是鸭子。在您的情况下,您可能希望它是可迭代的,或者您想以某个索引访问该项目。您应该这样做:即在块中for var:
或块var[idx]
内使用对象try
,如果遇到异常,它就不是鸭子。
var
发生字符串迭代可能会产生意外结果。
如果您只需要知道是否可以foo[123]
对变量使用符号,则可以使用以下命令检查__getitem__
属性的存在(这是python在通过索引访问时调用的内容)hasattr(foo, '__getitem__')