как проверить isinstance итерабельности в Python?

рассмотрите этот пример?

p = [1,2,3,4], (1,2,3), set([1,2,3])]

вместо проверки каждого типа, например

for x in p:
   if isinstance(x, list):
      xxxxx
   elif isinstance(x, tuple):
      xxxxxx
   elif isinstance(x, set):
      xxxxxxx

Есть ли эквивалент для следующего:

for element in something:
  if isinstance(x, iterable):
      do something

person brain storm    schedule 12.11.2013    source источник
comment
Самый простой подход - просто попробовать перебрать его и поймать исключение, если оно не сработает.   -  person BrenBarn    schedule 12.11.2013


Ответы (2)


Вы можете попробовать использовать Iterable ABC из модуля collections:

In [1]: import collections

In [2]: p = [[1,2,3,4], (1,2,3), set([1,2,3]), 'things', 123]

In [3]: for item in p:
   ...:     print isinstance(item, collections.Iterable)
   ...:     
True
True
True
True
False
person RocketDonkey    schedule 12.11.2013
comment
Импорт Iterable из collections устарел и не работает в Python 3.8+. Вместо этого импортируйте из collections.abc, например from collections.abc import Iterable. - person Demitri; 13.08.2019
comment
Если вы хотите использовать collections.abc.Iterable в качестве универсального типа (например, Iterable[int]) в Python 3.8 или ранее, вы также должны сделать from __future__ import annotations - person BallpointBen; 22.02.2021
comment
@BallpointBen Я думаю, вы путаете collections.abc.Iterable с typing.Iterable. - person c z; 26.02.2021
comment
@cz Python в наши дни меняется так быстро ... Взгляните на Pep 585, в нем говорится, что импорт типов, существующих в collections.abc, из typing устарел; их импорт из collections.abc - правильный способ сделать это в Python 3.9+ и в Python 3.7+ с from __future__ import annotations. - person BallpointBen; 26.02.2021

Вы можете проверить, есть ли в объекте атрибут __iter__, чтобы убедиться, является ли он повторяемым или нет.

a = [1, 2, 3]
b = {1, 2, 3}
c = (1, 2, 3)
d = {"a": 1}
f = "Welcome"
e = 1
print (hasattr(a, "__iter__"))
print (hasattr(b, "__iter__"))
print (hasattr(c, "__iter__"))
print (hasattr(d, "__iter__"))
print (hasattr(f, "__iter__") or isinstance(f, str))
print (hasattr(e, "__iter__"))

Вывод

True
True
True
True
True
False

Примечание. Несмотря на то, что строки итерируемы, в python 2 у них нет __iter__, но в python 3 он есть. Итак, в python 2 вы также можете захотеть иметь or isinstance(f, str)

person thefourtheye    schedule 12.11.2013
comment
Это не работает для строк, которые повторяются, но не имеют __iter__. - person Mark Reed; 12.11.2013
comment
@Mark, я думаю, что да. - person aIKid; 12.11.2013
comment
@MarkReed Я добавил примечание для строковой части. - person thefourtheye; 12.11.2013
comment
@aIKid В python 3 у нас есть, но не python 2 - person thefourtheye; 12.11.2013
comment
@aIKid - атрибут есть в Python 3, но не в 2.x - person Mark Reed; 12.11.2013
comment
А, понятно. Спасибо за информацию - person aIKid; 12.11.2013
comment
@Downvoter, пожалуйста, проверьте мой ответ сейчас и дайте мне знать, если он все еще ошибочен. - person thefourtheye; 12.11.2013