Как сравнить два словаря, исключая некоторые ключи? [Дубликат]

Ваш код getElementById() работает, поскольку идентификаторы должны быть уникальными, и поэтому функция всегда возвращает ровно один элемент (или null, если ни один не найден).

Однако getElementsByClassName() , querySelectorAll() и другие методы getElementsBy* возвращают массивный набор элементов. Итерации над ним, как и с реальным массивом:

var elems = document.getElementsByClassName('myElement');
for(var i = 0; i < elems.length; i++) {
    elems[i].style.size = '100px';
}

Если вы предпочитаете что-то более короткое, рассмотрите использование jQuery :

$('.myElement').css('size', '100px');

20
задан georg 10 May 2012 в 09:23
поделиться

6 ответов

def equal_dicts(d1, d2, ignore_keys):
    d1_filtered = dict((k, v) for k,v in d1.iteritems() if k not in ignore_keys)
    d2_filtered = dict((k, v) for k,v in d2.iteritems() if k not in ignore_keys)
    return d1_filtered == d2_filtered

EDIT: это может быть быстрее и экономичнее:

def equal_dicts(d1, d2, ignore_keys):
    ignored = set(ignore_keys)
    for k1, v1 in d1.iteritems():
        if k1 not in ignored and (k1 not in d2 or d2[k1] != v1):
            return False
    for k2, v2 in d2.iteritems():
        if k2 not in ignored and k2 not in d1:
            return False
    return True
18
ответ дан eumiro 22 August 2018 в 14:24
поделиться
  • 1
    +1 (лучше, чем мой ответ!) Кроме того, если кто-то использует Python 3, вы можете использовать dict-понимание (прокрутить вниз немного) вместо идиомы dict(<generator expression>). – huon 7 May 2012 в 12:09
  • 2
    Это простое решение, но в моей ситуации важна эффективность. – georg 7 May 2012 в 12:31
  • 3
    @ thg435 - см. мой обновленный ответ. – eumiro 7 May 2012 в 13:09
  • 4
    Второй, похоже, глючит: equal_dicts({'a':3,'b':5}, {'a':3,'b':6}, 'b') == False (должно быть верно). – georg 8 May 2012 в 09:52
  • 5
    Просто тестирование d[k1] != v1 без проверки k1 not in d2, а улавливание KeyError возможно быстрее (в третий раз избегает хэширования k1). – huon 8 May 2012 в 10:01

, если ваш словарь содержит списки или другие словари:

def equal_dicts(d1, d2, ignore_keys, equal):
    # print('got d1', d1)
    # print('got d2', d2)
    if isinstance(d1, str):
        if not isinstance(d2, str):
            return False
        return d1 == d2
    for k in d1:
        if k in ignore_keys:
            continue
        if not isinstance(d1[k], dict) and not isinstance(d1[k], list) and d2.get(k) != d1[k]:
            print(k)
            equal = False
        elif isinstance(d1[k], list):
            if not isinstance(d2.get(k), list):
                equal = False
            if len(d1[k]) != len(d2[k]):
                return False
            if len(d1[k]) > 0 and isinstance(d1[k][0], dict):
                if not isinstance(d2[k][0], dict):
                    return False
                d1_sorted = sorted(d1[k], key=lambda item: item.get('created'))
                d2_sorted = sorted(d2[k], key=lambda item: item.get('created'))
                equal = all(equal_dicts(x, y, ignore_keys, equal) for x, y in zip(d1_sorted, d2_sorted)) and equal
            else:
                equal = all(equal_dicts(x, y, ignore_keys, equal) for x, y in zip(d1[k], d2[k])) and equal
        elif isinstance(d1[k], dict):
            if not isinstance(d2.get(k), dict):
                equal = False
            print(k)
            equal = equal_dicts(d1[k], d2[k], ignore_keys, equal) and equal
    return equal
0
ответ дан Ahmad sibai 22 August 2018 в 14:24
поделиться

Очень very грубо, вы можете просто удалить любые игнорируемые ключи и сравнить эти словари:

def equal_dicts(d1, d2, ignore_keys=()):
    d1_, d2_ = d1.copy(), d2.copy()
    for k in ignore_keys:
        try:
            del d1_[k]
        except KeyError: 
            pass
        try:
            del d2_[k]
        except KeyError: 
            pass

    return d1_ == d2_

(Заметим, что здесь нам не нужна глубокая копия, мы просто нужно избегать модификации d1 и d2.)

1
ответ дан huon 22 August 2018 в 14:24
поделиться

Оптимальное решение для случая игнорирования только одного ключа

return all(
    (x == y or (x[1] == y[1] == 'key to ignore')) for x, y in itertools.izip(
          d1.iteritems(), d2.iteritems()))
0
ответ дан Paul Roub 22 August 2018 в 14:24
поделиться
  • 1
    Опасайтесь: возможно, это было неправильно во всех случаях в более ранних версиях Python (например, хэш-таблицы разного размера и т. Д.), Но аналогичная реализация, безусловно, более длительная работа в Python 3.6+, поскольку методы dict.items () и т. Д. Теперь возвращают элементы в режиме ввода- порядок, а не хэш-таблица. – intgr 31 October 2017 в 13:44
def compare_dict(d1, d2, ignore):
    for k in d1:
        if k in ignore:
            continue
        try:
            if d1[k] != d2[k]:
                return False
        except KeyError:
            return False
    return True

Редактирование комментария: вы можете сделать что-то вроде compare_dict(d1, d2, ignore) and compare_dict(d2, d1, ignore) или дублировать for

def compare_dict(d1, d2, ignore):
    ignore = set(ignore)
    for k in d1:
        if k in ignore:
            continue
        try:
            if d1[k] != d2[k]:
                return False
        except KeyError:
            return False

    for k in d2:
        if k in ignore:
            continue
        try:
            if d1[k] != d2[k]:
                return False
        except KeyError:
            return False
    return True

. Все быстрее и чище! Обновление: набор трансляции (игнорирование)

1
ответ дан StefanNch 22 August 2018 в 14:24
поделиться
  • 1
    Спасибо, но я не думаю, что это сработает, когда d2 имеет дополнительные ключи. – georg 7 May 2012 в 12:33

Использование понятий dict:

>>> {k: v for k,v in d1.items() if k not in ignore_keys} == \
... {k: v for k,v in d2.items() if k not in ignore_keys}

Вместо этого используйте .viewitems() на Python 2.

10
ответ дан wim 22 August 2018 в 14:24
поделиться
  • 1
    Это будет работать в Python 2.7 и 3. – Chris Morgan 7 May 2012 в 12:14
  • 2
    Спасибо, но см. Мой комментарий к ответу eumiro. Я предпочитаю не строить две дорогие структуры памяти, чтобы сравнить их. – georg 7 May 2012 в 12:32
  • 3
    то вы можете написать цикл вручную, но вы можете найти понимание быстрее в любом случае из-за реализации C – wim 7 May 2012 в 13:32
Другие вопросы по тегам:

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