Как бы вы проверили, является ли переменная словарём в python?
Например, я бы хотел, чтобы он просматривал значения в словаре, пока не найдет словарь. Затем переберите тот, который он находит:
dict = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}
for k, v in dict.iteritems():
if ###check if v is a dictionary:
for k, v in v.iteritems():
print(k, ' ', v)
else:
print(k, ' ', v)
python
dictionary
Райли
источник
источник
isinstance(v, collections.abc.Mapping)
. Другими словами, это не является точной копией «Различия между isinstance () и type ()».Ответы:
Вы могли бы использовать
if type(ele) is dict
или использовать то,isinstance(ele, dict)
что будет работать, если вы подклассdict
:источник
isinstance(ele, collections.Mapping)
. Она работаетdict()
,collections.OrderedDict()
иcollections.UserDict()
. Пример в вопросе достаточно специфичен для ответа Падриака, но не достаточно хорош для общего случая.ele.items()
почему вы проверяете тип? ЭСПЦ / уток-типирование работает здесь, просто обернутьfor k,v in ele.items()
вtry...except (AttributeError, TypeError)
. Если возникает исключение, вы знаете,ele
что нет,items
что приводит к итерации ...items()
метод 2., который, как оказалось, давал итерируемое и 3. где каждый элемент этого итерируемого можно представить как 2 -кратный. На данный момент ваш пользовательский объект уже реализовал половину диктата. В целях перечисленного кода мы заботились только об условном расширении вложенного элемента, и ваш пользовательский объект уже реализует это. (Немного иронично, что вы критикуете комментарий @Alexander Ryzhov за то, что он слишком общий, но теперь поднимите общий случай)items()
что дает вложенную итерацию).collections.abc.Mapping
заметить, что они могут быть одинаковыми, ноcollections.abc
недоступны до Python 3.3.collections.Mapping
псевдоним все еще доступен в Python 3.6, но не документирован, так что, вероятно, следует отдать предпочтениеcollections.abc.Maping
.Это отличный вопрос, но, к сожалению, самый голосующий голос приводит к плохой рекомендации
type(obj) is dict
.(Обратите внимание, что вы также не должны использовать
dict
в качестве имени переменной - это имя встроенного объекта.)Если вы пишете код, который будет импортироваться и использоваться другими, не предполагайте, что они будут использовать встроенную функцию dict напрямую - делая это предположение, делает ваш код более негибким, и в этом случае создавайте легко скрытые ошибки, которые не будут вызывать ошибку программы. ,
Я настоятельно рекомендую, для целей корректности, удобства обслуживания и гибкости для будущих пользователей, никогда не иметь менее гибких, недиоматических выражений в вашем коде, когда есть более гибкие идиоматические выражения.
is
является испытанием для идентичности объекта . Он не поддерживает наследование, не поддерживает абстракции и не поддерживает интерфейс.Поэтому я предоставлю несколько вариантов, которые делают.
Поддержка наследования:
Это первая рекомендация я хотел бы сделать, потому что она позволяет пользователям поставить свой собственный подкласс Dict, или
OrderedDict
,defaultdict
илиCounter
из коллекции модуля:if isinstance(any_object, dict):
Но есть еще более гибкие варианты.
Поддерживающие абстракции:
Это позволяет пользователю вашего кода использовать собственную пользовательскую реализацию абстрактного отображения, которая также включает в себя любой подкласс класса
dict
, и при этом получать правильное поведение.Используйте интерфейс
Вы обычно слышите совет ООП "программа для интерфейса".
Эта стратегия использует преимущества полиморфизма Python или типизации уток.
Поэтому просто попытайтесь получить доступ к интерфейсу, перехватывая определенные ожидаемые ошибки (
AttributeError
в случае, если их нет,.items
аTypeError
в случае, если ониitems
не могут быть вызваны) с разумным отступлением - и теперь любой класс, реализующий этот интерфейс, выдаст вам свои элементы (примечание.iteritems()
отсутствует в Python 3):Возможно, вы подумали, что использование утки, как это, заходит слишком далеко, допуская слишком много ложных срабатываний, и это может быть в зависимости от ваших целей для этого кода.
Вывод
Не используйте
is
для проверки типов для стандартного потока управления. Используйтеisinstance
, рассматривайте абстракции какMapping
илиMutableMapping
, и вообще избегайте проверки типов, используя интерфейс напрямую.источник
OP не исключил начальную переменную, поэтому для полноты здесь показано, как обрабатывать общий случай обработки предполагаемого словаря, который может включать элементы в качестве словарей.
Также, следуя чистому Python (3.8), рекомендуем проверить способ словаря в приведенных выше комментариях.
источник
dict.iteritems()
не существует в Python 3, вы должны использоватьdict.items()
вместо этого.