如何根据数据类型在python中设置条件?

时间:2013-01-01 18:45:00

标签: python types conditional

这个问题似乎令人难以置信,但我无法弄清楚。我知道你可以检查python中的数据类型,但是如何根据数据类型设置条件?例如,如果我必须编写一个通过字典/列表排序并将所有整数相加的代码,那么如何隔离搜索以仅查找整数?

我想一个简单的例子看起来像这样:

y = []
for x in somelist:
    if type(x) == <type 'int'>:  ### <--- psuedo-code line
    y.append(x)
print sum(int(z) for z in y)

因此,对于第3行,我将如何设置这样的条件?

6 个答案:

答案 0 :(得分:36)

怎么样,

if isinstance(x, int):

但更清洁的方式就是

sum(z for z in y if isinstance(z, int))

答案 1 :(得分:8)

有一个非常大的&#34;它取决于&#34;在Python中进行类型检查。有很多方法可以处理类型,并且都有其优点和缺点。在Python3中,还出现了更多。

  • 明确的类型相等

类型是第一类对象,您可以像对待任何其他值一样对待它们。 因此,如果您希望某事物的类型等于int,则只需测试它:

if type(x) == int:

这是最严格的测试类型:它需要完全类型相等。通常,这不是你想要的:

  • 它排除了替代类型:float无效,即使它出于多种用途就像int一样。
  • 它排除了子类和抽象类型:一个漂亮的打印int子类或enum将被拒绝,即使它们是逻辑上的整数。
    • 严重限制了可移植性:Python2字符串可以 strunicode,而整数可以 intlong

请注意,显式类型相等 用于低级操作:

  • 某些类型的不能进行子类化,例如slice。明确的检查在这里更明确。
  • 某些低级操作(如序列化或C-API)需要特定类型。

<强>变体

还可以对__class__属性执行比较:

if x.__class__ == int:

请注意,如果某个类定义了__class__属性,则这与type(x)不同。

当有多个要检查的类时,使用dict调度操作更易于扩展,并且可以比显式检查更快(≥5-10种类型)。 这对转换和序列化特别有用:

dispatch_dict = {float: round, str: int, int: lambda x: x}
def convert(x):
    converter = self.dispatch_dict[type(x)]  # lookup callable based on type
    return converter(x)
  • 对显式类型进行实例检查

惯用类型测试使用isinstance builtin

if isinstance(x, int):

此检查既准确又高效。这通常是人们想要检查类型的原因:

  • 它正确处理子类型。一个漂亮的打印int子类仍将通过此测试。
  • 它允许一次检查多种类型。在Python2中,执行isinstance(x, (int, long))可以获得所有内置整数。

最重要的是,在大多数情况下,缺点可以忽略不计:

  • 它仍然接受以怪异方式表现的时髦子类。由于可以使任何以奇怪的方式行事,因此这是徒劳的。
  • 很容易限制:许多人在任何序列(例如isinstance(x, list))或甚至可迭代(例如tuple)时会检查generator做得也好。对于通用库而言,这比脚本或应用程序更受关注。

<强>变体

如果您已有类型,issubclass的行为相同:

if issubclass(x_type, int):
  • 抽象类型的实例检查

Python有一个abstract base classes的概念。松散地说,这些表达了类型的含义,而不是它们的层次结构:

if isinstance(x, numbers.Real):  # accept anything you can sum up like a number

换句话说,类型(x)不一定numbers.Real继承,但必须表现。 不过,这是一个非常复杂和困难的概念:

  • 如果您正在寻找基本类型,那通常会有些过分。在大多数情况下,整数只是int
  • 来自其他语言的人经常会混淆其概念。
    • 区别于例如C ++,重点是抽象基础类,而不是抽象基类。
    • ABCs可以像Java接口一样使用,但可能仍具有具体的功能。

但是,它对通用库和抽象非常有用。

  • 许多函数/算法不需要显式类型,只需要它们的行为。
    • 如果您只需要按键查找内容,dict会将您限制为特定的内存类型。相比之下,collections.abc.Mapping还包括数据库包装器,大型磁盘支持的字典,惰性容器......以及dict
  • 它允许表达部分类型约束。
    • 没有严格的基类型实现迭代。但是,如果您针对collections.abc.Iterable检查对象,则它们都在for循环中工作。
  • 它允许创建显示为相同抽象类型的单独的优化实现。

虽然通常不需要一次性脚本,但我强烈建议将其用于超出一些python版本的任何内容。

  • 暂定转换

处理类型的惯用方法不是测试它们,而是假设它们是兼容的。如果您已经预期输入中存在一些错误的类型,只需跳过所有不兼容的内容:

try:
    ix = int(x)
except (ValueError, TypeError):
    continue  # not compatible with int, try the next one
else:
    a.append(ix)

这实际上不是类型检查,但通常用于相同的意图。

  • 保证您的输出中有预期的类型。
  • 在转换错误类型方面有一些有限的余地,例如:将float专门化为int
  • 无需您知道哪些类型符合int

主要的缺点是它是一种明显的转变。

  • 你可以默默接受&#34;错误&#34;值,例如转换包含文字的str
  • 它甚至可以毫无疑问地转换出足够好的类型,例如:当你需要数字时floatint

转换是某些特定用例的有效工具。如果你大致知道你的输入是什么,它最有效,并且必须保证你的输出。

  • 控制输入

最好的做法是确保您不必首先检查类型。这是一个元主题,因为它主要取决于用例。

此处,somelist的来源绝不应该将非数字放入其中。

答案 2 :(得分:0)

让我声明int类型的变量x

x = 2
if type(x) == type(1) or isinstance(x, int):  
    # do something

两者都很好。

答案 3 :(得分:-1)

易于使用的类型。

import types
k = 5
if(type(k)==types.IntType):
   print "int"

这是一个快速目录(类型):

['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'CodeType', 'ComplexType', 'DictProxyType', 'DictType', 'DictionaryType', 'EllipsisType', 'FileType', 'FloatType', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'InstanceType', 'IntType', 'LambdaType', 'ListType', 'LongType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'NoneType', 'NotImplementedType', 'ObjectType', 'SliceType', 'StringType', 'StringTypes', 'TracebackType', 'TupleType', 'TypeType', 'UnboundMethodType', 'UnicodeType', 'XRangeType', '__builtins__', '__doc__', '__file__', '__name__', '__package__']

答案 4 :(得分:-1)

您可以在操作员的两侧使用类型功能。像这样:

if type(x) == type(1):

答案 5 :(得分:-1)

您可以像这样简单地使用类型和等于运算符

if (type(x) == int):