перебирая список с разными элементами - PullRequest
0 голосов
/ 24 августа 2018

У меня есть три типа элементов: диктет, список с одним диктом и список с несколькими диктовками.

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"])

Есть ли лучший способ сделать это?

Ответы [ 4 ]

0 голосов
/ 24 августа 2018

Если вы хотите сделать это для более вложенных элементов, таких как список в диктовке в списке, вы можете создать функцию для каждого возможного типа данных.

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
0 голосов
/ 24 августа 2018

Вы можете проверить тип данных явно:

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. Этот фрагмент иллюстрирует, почему вы не должны этого делать.

0 голосов
/ 24 августа 2018

Вы можете использовать рекурсивный генератор с вашей идеей try / except:

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_ или L вместо list.

0 голосов
/ 24 августа 2018

Вы можете использовать isinstance

Ex:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...