Как установить условие в python на основе типов данных?

этот вопрос кажется умопомрачительно простым, но я не могу понять это. Я знаю, что вы можете проверить типы данных в 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, как бы я установил такой условно?

4 ответов


Как насчет

if isinstance(x, int):

но более чистый способ был бы просто

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

существует действительно большой "это зависит" от проверки типа в Python. Существует много способов борьбы с типами, и у всех есть свои плюсы и минусы. С Python3 появилось еще несколько.

  • явное равенство типа

типы являются объектами первого класса, и вы можете рассматривать их как любое другое значение. Поэтому, если вы хотите, чтобы тип чего-то был равен int, просто проверить это:

if type(x) == int:

это самый ограничительный тип тестирования: требуется точно равенство типа. Часто, это не то, что вы хотите:

  • он исключает типы заменителей: a float не будет действительным, даже если он ведет себя как int много целей.
  • это исключает подклассы и абстрактные типы: pretty-printing int подкласс или enum будет отклонено, даже если они являются логически целыми числами.
    • это сильно ограничивает переносимость: Python2 Строки могут быть или str или unicode, и целые числа могут быть или int или long.

обратите внимание, что явное равенство типов и свои пользы для низкоуровневых деятельностей:

  • некоторые типы не может быть подклассом, например slice. Явная проверка, Ну, более явная здесь.
  • некоторые низкоуровневые операции, такие как сериализация или C-API, требуют определенных типов.

вариантов

сравнение также может быть выполнено в отношении :

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)) получает все встроенные целые числа.

самое главное, недостатки незначительны большую часть времени:

  • он по-прежнему принимает фанки подклассы, которые ведут себя странным образом. С что-нибудь можно заставить вести себя странно, это бесполезно, чтобы защититься.
  • это может быть легко слишком restrictive: многие люди проверяют isinstance(x, list) когда любая последовательность (например,tuple) или даже iterable (например, a generator) было бы неплохо. Это больше касается библиотек общего назначения, чем скриптов или приложений.

вариантов

если у вас уже есть типа issubclass ведет себя так же:

if issubclass(x_type, int):
  • проверка экземпляра на абстрактный тип

Python имеет понятие абстрактные базовые классы. Грубо говоря, эти выражайте значение типов, а не их иерархию:

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

другими словами, тип (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 to int.
  • он работает без вас зная, какие типы соответствуют int.

основным недостатком является то, что это явное преобразование.

  • вы можете молча принимать "неправильные" значения, например, преобразование str содержащего литерал.
  • он без необходимости преобразует даже типы, которые были бы достаточно хороши, например float to int когда вам просто нужны номера.

преобразование является эффективным инструментом для определенных случаев использования. Это работает лучше всего, если вы знаете примерно, что ваш вход, и необходимо сделать гарантии о вашем выходе.

  • управление входными

лучший способ действий-убедиться, что вам никогда не придется проверять тип в первую очередь. Это немного мета-тема, так как она сильно зависит от варианта использования.

здесь Источник somelist никогда не следовало вкладывать в него номера.


легкий в использовании типа.

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

вот быстрый dir (типы):

['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__']

вы можете использовать функцию type с обеих сторон оператора. Вот так:

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