Фильтр dict содержит только определенные клавиши?

У меня есть dict, который содержит целую кучу записей. Меня интересуют только некоторые из них. Есть ли простой способ обрезать все остальные?

Ответ 1

Построение нового dict:

dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }

Использует понимание словаря.

Если вы используете версию, которой их нет (например, Python 2.6 и ранее), сделайте ее dict((your_key, old_dict[your_key]) for ...). Это то же самое, хотя и уродливое.

Обратите внимание, что это, в отличие от версии jnnnnn, имеет стабильную производительность (зависит только от количества ваших_keys) для old_dict любого размера. Как с точки зрения скорости, так и с памятью. Поскольку это выражение генератора, он обрабатывает один элемент за раз, и он не просматривает все элементы old_dict.

Удаление всего на месте:

unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]

Ответ 2

Чуть более элегантное понимание диктата:

foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}

Ответ 3

Вот пример в python 2.6:

>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}

Фильтрационная часть - это оператор if.

Этот метод медленнее, чем ответ delnan, если вы хотите только выбрать несколько очень многих клавиш.

Ответ 4

Вы можете сделать это с помощью project из моего funcy:

from funcy import project
small_dict = project(big_dict, keys)

Также посмотрите select_keys.

Ответ 5

Этот один лайнер должен работать:

dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])

Вот пример:

my_dict = {"a":1,"b":2,"c":3,"d":4}
wanted_keys = ("c","d")

# run it
In [10]: dictfilt(my_dict, wanted_keys)
Out[10]: {'c': 3, 'd': 4}

Это базовое понимание списка, повторяющееся по вашим ключам dict (i в x), и выводит список пар кортежей (ключ, значение), если ключ живет в вашем списке нужных ключей (y). A dict() обертывает все, что выводится как объект dict.

Ответ 6

Код 1:

dict = { key: key * 10 for key in range(0, 100) }
d1 = {}
for key, value in dict.items():
    if key % 2 == 0:
        d1[key] = value

Код 2:

dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}

Код 3:

dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}

Все значения производительности кода измеряются с помощью timeit с использованием number = 1000 и собираются 1000 раз для каждой части кода.

введите описание изображения здесь

Для python 3.6 производительность трех способов фильтрации ключей dict почти одинакова. Для python 2.7 код 3 немного быстрее.

Ответ 7

Учитывая ваш оригинальный словарь orig и набор записей, которые вас интересуют keys:

filtered = dict(zip(keys, [orig[k] for k in keys]))

который не так хорош, как ответ delnan, но должен работать в каждой интересующей Python версии. Он, однако, является хрупким для каждого элемента keys, существующего в вашем исходном словаре.

Ответ 8

На основании принятого ответа delnan.

Что делать, если один из ваших желаемых ключей не находится в old_dict? Решение delnan выдает исключение KeyError, которое вы можете поймать. Если это не то, что вам нужно, возможно, вы хотите:

  • включают только ключи, которые активируют как в old_dict, так и в вашем наборе желаемых клавиш.

    old_dict = {'name':"Foobar", 'baz':42}
    wanted_keys = ['name', 'age']
    new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}
    
    >>> new_dict
    {'name': 'Foobar'}
    
  • имеют значение по умолчанию для ключей, которые не установлены в old_dict.

    default = None
    new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
    
    >>> new_dict
    {'age': None, 'name': 'Foobar'}
    

Ответ 9

Эта функция выполнит трюк:

def include_keys(dictionary, keys):
    """Filters a dict by only including certain keys."""
    key_set = set(keys) & set(dictionary.keys())
    return {key: dictionary[key] for key in key_set}

Так же, как версия delnan, эта использует понимание словаря и имеет стабильную производительность для больших словарей (зависит только от количества ключей, которые вы разрешаете, а не от общего количества ключей в словаре).

И так же, как версия MyGGan, этот позволяет вашему списку ключей включать ключи, которые могут не существовать в словаре.

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

def exclude_keys(dictionary, keys):
    """Filters a dict by excluding certain keys."""
    key_set = set(dictionary.keys()) - set(keys)
    return {key: dictionary[key] for key in key_set}

Обратите внимание, что в отличие от версии delnan операция не выполняется на месте, поэтому производительность связана с количеством ключей в словаре. Однако преимущество этого заключается в том, что функция не будет изменять словарь.

Изменить: Добавлена ​​отдельная функция для исключения определенных ключей из dict.

Ответ 10

Другой вариант:

content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())

Но вы получаете list (Python 2) или итератор (Python 3), возвращаемый filter(), а не dict.

Ответ 11

Короткая форма:

[s.pop(k) for k in list(s.keys()) if k not in keep]

Как следует из большинства ответов, чтобы сохранить краткость, мы должны создать дублирующий объект, будь то list или dict. Это создает отбрасывание list, но удаляет ключи в оригинале dict.

Ответ 12

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

d = {
'a' : 1,
'b' : 2,
'c' : 3
}
x = {key:d[key] for key in d.keys() - {'c', 'e'}} # Python 3
y = {key:d[key] for key in set(d.keys()) - {'c', 'e'}} # Python 2.*
# x is {'a': 1, 'b': 2}
# y is {'a': 1, 'b': 2}

Ответ 13

Вот еще один простой метод с использованием del в одном вкладыше:

for key in e_keys: del your_dict[key]

e_keys - список исключаемых ключей. Это обновит ваш диктант, а не даст вам новый.

Если вы хотите создать новый выходной файл dict, сделайте его копию перед удалением:

new_dict = your_dict.copy()           #Making copy of dict

for key in e_keys: del new_dict[key]