У меня есть три типа элементов: dict, список с одним dict и список с несколькими dicts.
a = {"foo":1}
b = [{"foo":2}]
c = [{"foo":3}, {"foo":4}]
list = [a, b, c]
Я хочу напечатать все четыре значения. Единственные способы, которыми я придумал, - либо проверить type()
каждого элемента list
, либо использовать try
и except
, например:
for i in list:
try: # i is a dict
print(i["foo"])
except: # i a list
for e in i:
print(e["foo"])
Есть ли лучший способ сделать это?
Вы можете использовать isinstance
Пример:
a = {"foo":1}
b = [{"foo":2}]
c = [{"foo":3}, {"foo":4}]
l = [a, b, c]
for i in l:
if isinstance(i, dict): #Check if dict object
print(i["foo"])
elif isinstance(i, list): #Check if list object
for j in i:
print(j["foo"])
Выход:
1
2
3
4
Если вы хотите сделать это для более вложенных элементов, таких как список в dict в списке, вы можете создать функцию для каждого возможного типа данных.
class Printer():
def print_element(self, element):
if isinstance(element, dict):
self._print_dict(element)
elif isinstance(element, list):
self._print_list(element)
else:
print(element)
def _print_dict(self, element):
for key,value in element.items():
self.print_element(value)
def _print_list(self, element):
for value in element:
self.print_element(value)
a = {"foo":1}
b = [{"foo":2}]
c = [{"foo":3}, {"foo":4}, [1, {"foo":[9,8,7,6]}]]
Printer().print_element(c)
Выход:
3
4
1
9
8
7
6
Вы можете проверить тип данных явно:
mylist = [a, b, c]
for i in mylist:
if isinstance(i,dict):
print(i["foo"])
elif isinstance(i,list):
for e in i:
print(e["foo"])
Но это не сработает, если вы вызовете свой list
переменных. Этот фрагмент иллюстрирует, почему вы не должны этого делать.
Вы можете использовать рекурсивный генератор с помощью try
/except
idea:
a = {"foo":1}
b = [{"foo":2}]
c = [{"foo":3}, {"foo":4}]
L = [a, b, c]
def get_values(x):
for i in x:
try:
yield i['foo']
except TypeError:
yield from get_values(i)
res = list(get_values(L)) # [1, 2, 3, 4]
Альтернативно, используя "isinstance:
def get_values(x):
for i in x:
if isinstance(i, dict):
yield i['foo']
else:
yield from get_values(i)
Обратите внимание: вы никогда не должны list_
переменные после встроенных модулей, например, используйте list_
или L
вместо list
.