Поиск через вложенные словари в python [duplicate]

Ниже приведен короткий гибкий фрагмент, который преобразует строку datetime в безопасном для кросс-браузера стиле, как nicel, подробно описанный @ drankin2112.

var inputTimestamp = "2014-04-29 13:00:15"; //example

var partsTimestamp = inputTimestamp.split(/[ \/:-]/g);
if(partsTimestamp.length < 6) {
    partsTimestamp = partsTimestamp.concat(['00', '00', '00'].slice(0, 6 - partsTimestamp.length));
}
//if your string-format is something like '7/02/2014'...
//use: var tstring = partsTimestamp.slice(0, 3).reverse().join('-');
var tstring = partsTimestamp.slice(0, 3).join('-');
tstring += 'T' + partsTimestamp.slice(3).join(':') + 'Z'; //configure as needed
var timestamp = Date.parse(tstring);

Ваш браузер должен предоставить тот же результат временной метки, что и Date.parse с:

(new Date(tstring)).getTime()
19
задан Fredrick Brennan 19 February 2013 в 18:29
поделиться

3 ответа

, когда вы рекурсируете, вам нужно return получить результат _finditem

def _finditem(obj, key):
    if key in obj: return obj[key]
    for k, v in obj.items():
        if isinstance(v,dict):
            return _finditem(v, key)  #added return statement

. Чтобы исправить фактический алгоритм, вам нужно понять, что _finditem возвращает None, если он 't найти что-нибудь, поэтому вам нужно проверить это явно, чтобы предотвратить ранний возврат:

def _finditem(obj, key):
    if key in obj: return obj[key]
    for k, v in obj.items():
        if isinstance(v,dict):
            item = _finditem(v, key)
            if item is not None:
                return item

Конечно, это не удастся, если у вас есть None значения в любом из ваших словарей. В этом случае вы можете настроить дозор object() для этой функции и вернуть это в случае, если вы ничего не нашли. Затем вы можете проверить sentinel, чтобы узнать, нашли ли вы что-то или нет.

42
ответ дан mgilson 18 August 2018 в 01:39
поделиться
  • 1
    Это, по-видимому, самая распространенная ошибка при записи рекурсивных функций. – Daniel Roseman 19 February 2013 в 18:30
  • 2
    @DanielRoseman - пожимает плечами - Я сделал эту ошибку себе несколько раз. Но это подсказка, когда ваша функция возвращает None, и вы не знаете, почему ;-) – mgilson 19 February 2013 в 18:31
  • 3
    Спасибо, это должно было быть очевидно. Я смотрел на это в течение хорошего часа! – Fredrick Brennan 19 February 2013 в 18:32
  • 4
    @frb - Нет проблем. Такие вещи случаются со всеми. – mgilson 19 February 2013 в 18:33
  • 5
    @frb - проверьте обновление. Я думаю, что это исправить. – mgilson 19 February 2013 в 18:56

Вот как это сделать, используя шаблон «stack» и «stack of iterators» (кредиты Gareth Rees):

def search(d, key, default=None):
    """Return a value corresponding to the specified key in the (possibly
    nested) dictionary d. If there is no item with that key, return
    default.
    """
    stack = [iter(d.items())]
    while stack:
        for k, v in stack[-1]:
            if isinstance(v, dict):
                stack.append(iter(v.items()))
                break
            elif k == key:
                return v
        else:
            stack.pop()
    return default

print(search({"B": {"A": 2}}, "A")) будет печатать 2.

3
ответ дан alecxe 18 August 2018 в 01:39
поделиться

Вот функция, которая выполняет поиск словаря, который содержит как вложенные словари, так и списки. Он создает список значений результатов.

def get_recursively(search_dict, field):
    """
    Takes a dict with nested lists and dicts,
    and searches all dicts for a key of the field
    provided.
    """
    fields_found = []

    for key, value in search_dict.iteritems():

        if key == field:
            fields_found.append(value)

        elif isinstance(value, dict):
            results = get_recursively(value, field)
            for result in results:
                fields_found.append(result)

        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    more_results = get_recursively(item, field)
                    for another_result in more_results:
                        fields_found.append(another_result)

    return fields_found
15
ответ дан Dmitry Nazarov 18 August 2018 в 01:39
поделиться
Другие вопросы по тегам:

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