Как извлекать элементы внутри вложенных списков, содержащих вложенные словари в python [duplicate]

Я получил решение для меня:

Откройте «Менеджер конфигурации SQL Server»

Теперь нажмите «Конфигурация сети SQL Server» и нажмите «Протоколы для ] Имя "

Щелкните правой кнопкой мыши на« TCP / IP »(убедитесь, что оно включено) Нажмите« Свойства »

Теперь выберите вкладку« IP-адреса »- и-Go к последней записи «IP All»

Введите «TCP-порт» 1433.

Теперь перезапустите «SQL Server .Name». используя «services.msc» (winKey + r)

Он будет работать ...

1
задан Snobby 21 January 2017 в 10:49
поделиться

1 ответ

Вот семейство рекурсивных генераторов, которые можно использовать для поиска объекта, состоящего из диктов и списков. find_key дает кортеж, содержащий список ключей словаря и индексы списка, которые приводят к ключу, который вы передаете; кортеж также содержит значение, связанное с этим ключом.

def find_key(obj, key):
    if isinstance(obj, dict):
        yield from iter_dict(obj, key, [])
    elif isinstance(obj, list):
        yield from iter_list(obj, key, [])

def iter_dict(d, key, indices):
    for k, v in d.items():
        if k == key:
            yield indices + [k], v
        if isinstance(v, dict):
            yield from iter_dict(v, key, indices + [k])
        elif isinstance(v, list):
            yield from iter_list(v, key, indices + [k])

def iter_list(seq, key, indices):
    for k, v in enumerate(seq):
        if isinstance(v, dict):
            yield from iter_dict(v, key, indices + [k])
        elif isinstance(v, list):
            yield from iter_list(v, key, indices + [k])

# test

data = {
    '1_data': {
        '4_data': [
            {'5_data': 'hooray'},
            {'3_data': 'hooray2'}
        ], 
        '2_data': []
    }
}

for t in find_key(data, '3_data'):
    print(t)

output

(['1_data', '4_data', 1, '3_data'], 'hooray2')

Чтобы получить один ключ, если он является генератором, он найдет все соответствующие ключи. вы можете передать find_key в функцию next. И если вы хотите использовать список ключей для извлечения связанного значения, вы можете использовать простой цикл for.

seq, val = next(find_key(data, '3_data'))
print('seq:', seq, 'val:', val)

obj = data
for k in seq:
    obj = obj[k]
print('obj:', obj, obj == val)

output

seq: ['1_data', '4_data', 1, '3_data'] val: hooray2
obj: hooray2 True

Если ключ может быть отсутствует, затем дайте next соответствующий кортеж по умолчанию. Например:

seq, val = next(find_key(data, '6_data'), ([], None))
print('seq:', seq, 'val:', val)
if seq:
    obj = data
    for k in seq:
        obj = obj[k]
    print('obj:', obj, obj == val)

output

seq: [] val: None

Обратите внимание, что этот код предназначен для Python 3. Чтобы запустить его на Python 2, вам необходимо заменить все yield from например, заменить

yield from iter_dict(obj, key, [])

на

for u in iter_dict(obj, key, []):
    yield u

Как это работает

Чтобы понять, как работает этот код, вам нужно быть знакомым с рекурсия и с генераторами Python . Вы также можете найти эту страницу полезной: Понимание генераторов в Python ; существуют также различные обучающие программы для генераторов Python, доступные в Интернете.

Объект Python, возвращенный json.load или json.loads, обычно является dict, но также может быть списком. Мы передаем этот объект генератору find_key в качестве obj arg, а также строку key, которую хотим найти. find_key затем вызывает либо iter_dict, либо iter_list, в случае необходимости, передавая им объект, ключ и пустой список indices, который используется для сбора ключей dict и индексов списка, которые приводят к ключу, который мы want.

iter_dict выполняет итерацию по каждой (k, v) паре на верхнем уровне своего d dict arg. Если k соответствует клавише, которую мы ищем, то текущий indices список будет добавлен с добавленным к нему k вместе со связанным значением. Поскольку iter_dict рекурсивно, полученные пары (индексы список, значение) передаются до предыдущего уровня рекурсии, в конечном итоге доходя до find_key, а затем кода, который называется find_key. Обратите внимание, что это «базовый случай» нашей рекурсии: это часть кода, которая определяет, ведет ли этот путь рекурсии к нужному ключу. Если путь рекурсии никогда не находит ключ, соответствующий ключевому слову, который мы ищем, тогда этот путь рекурсии ничего не добавит к indices, и он завершится без каких-либо изменений.

Если текущий v является dict, тогда нам нужно изучить все пары (ключ, значение), которые он содержит. Мы делаем это путем рекурсивного вызова iter_dict, передавая, что v является его стартовым объектом и текущим indices списком. Если текущий v является списком, мы вместо этого вызываем iter_list, передавая ему одни и те же аргументы.

iter_list работает аналогично iter_dict, за исключением того, что в списке нет никаких ключей, это только содержит значения, поэтому мы не выполняем тест k == key, мы просто рекурсируем в любые dicts или списки, которые содержит исходный список.

Конечным результатом этого процесса является то, что когда мы перебираем find_key мы получаем пары (индексы, значение), где каждый список indices представляет собой последовательность ключей dict и индексов списка, которые успешно завершаются в элементе dict с помощью нашего желаемого ключа, а value - это значение, связанное с этим конкретным ключом .

Если вы хотите увидеть некоторые другие примеры использования этого кода, см. , как изменить ключ вложенных Json и . Как я могу выбрать глубоко вложенный ключ: значения из словаря в python .

8
ответ дан PM 2Ring 19 August 2018 в 05:23
поделиться
  • 1
    Спасибо за функцию рекурсии. Я способ могу выполнить find_key (), но я получаю & quot; TypeError: Невозможно преобразовать объект 'list' в str неявно & quot; в выходе из строки в iter_dict (), пытаясь распечатать словарь. Любое решение? – Kaleab 2 November 2017 в 12:45
  • 2
    @Kaleab Мне нужно увидеть код (с некоторыми данными), который вызывает проблему. Поэтому добавьте его в свой вопрос , и я взгляну на него в ближайшее время. – PM 2Ring 2 November 2017 в 12:51
  • 3
    Жаль, что я не могу дать вам больше, чем один голос. Это было отличное объяснение и именно то, что я искал. Благодарю. – Colin Wu 16 March 2018 в 20:33
  • 4
    Я рад, что это помогло вам @ColinWu – PM 2Ring 17 March 2018 в 10:18
Другие вопросы по тегам:

Похожие вопросы: