Извлечь подмножество пар ключ-значение из объекта словаря Python?

У меня есть большой объект словаря, который имеет несколько ключевых пар значений (около 16), но меня интересуют только 3 из них. Каков наилучший способ (кратчайший / эффективный / самый элегантный) для достижения этого?

Лучшее, что я знаю:

bigdict = {'a':1,'b':2,....,'z':26} subdict = {'l':bigdict['l'], 'm':bigdict['m'], 'n':bigdict['n']} 

Я уверен, что есть более элегантный способ, чем это. Идеи?

  • Разница между u'string 'и unicode (строка)
  • Доступ к микрофону в Python
  • gi.repository Windows
  • easy_install или pip как ограниченный пользователь?
  • Любимые советы и возможности Django?
  • Смутно о __str__ в Python
  • Как мы можем сделать импорт __future__ глобальным?
  • Как использовать PIL для изменения размера и применения данных EXIF ​​в файл?
  • 9 Solutions collect form web for “Извлечь подмножество пар ключ-значение из объекта словаря Python?”

    Вы можете попробовать:

     dict((k, bigdict[k]) for k in ('l', 'm', 'n')) 

    … или в Python 3 Python версии 2.7 или новее (благодаря Fábio Diniz за то, что он работает и в версии 2.7 ) :

     {k: bigdict[k] for k in ('l', 'm', 'n')} 

    Обновление: Как указывает Ховард С. , я предполагаю, что вы знаете, что ключи будут в словаре – см. Его ответ, если вы не можете сделать это предположение. В качестве альтернативы, поскольку timbo указывает на комментарии, если вы хотите, чтобы ключ, отсутствующий в bigdict отображался в None , вы можете сделать:

     {k: bigdict.get(k, None) for k in ('l', 'm', 'n')} 

    Если вы используете Python 3, и вам нужны только нужные ключи в новом dict, которые действительно существуют в оригинале, вы можете использовать тот факт, что объекты представления реализуют некоторые заданные операции:

     {k: bigdict[k] for k in bigdict.keys() & {'l', 'm', 'n'}} 

    Немного короче, по крайней мере:

     wanted_keys = ['l', 'm', 'n'] # The keys you want dict((k, bigdict[k]) for k in wanted_keys if k in bigdict) 
     interesting_keys = ('l', 'm', 'n') subdict = {x: bigdict[x] for x in interesting_keys if x in bigdict} 

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

    Версия python 2:

     {k:v for k, v in bigDict.iteritems() if k in ('l', 'm', 'n')} 

    Версия python 3:

     {k:v for k, v in bigDict.items() if k in ('l', 'm', 'n')} 

    Немного сравнения скорости для всех упомянутых методов:

     Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Jan 29 2016, 14:26:21) [MSC v.1500 64 bit (AMD64)] on win32 In[2]: import numpy.random as nprnd keys = nprnd.randint(1000, size=10000) bigdict = dict([(_, nprnd.rand()) for _ in range(1000)]) %timeit {key:bigdict[key] for key in keys} %timeit dict((key, bigdict[key]) for key in keys) %timeit dict(map(lambda k: (k, bigdict[k]), keys)) %timeit dict(filter(lambda i:i[0] in keys, bigdict.items())) %timeit {key:value for key, value in bigdict.items() if key in keys} 100 loops, best of 3: 3.09 ms per loop 100 loops, best of 3: 3.72 ms per loop 100 loops, best of 3: 6.63 ms per loop 10 loops, best of 3: 20.3 ms per loop 100 loops, best of 3: 20.6 ms per loop 

    Как и ожидалось: наилучшим вариантом является понимание словаря.

    Вы также можете использовать карту (которая очень полезная функция, чтобы узнать все равно):

    sd = dict(map(lambda k: (k, l.get(k, None)), l))

    Пример:

    large_dictionary = {'a1':123, 'a2':45, 'a3':344} list_of_keys = ['a1', 'a3'] small_dictionary = dict(map(lambda key: (key, large_dictionary.get(key, None)), list_of_keys))

    PS. Я заимствовал ключ .get (key, None) из предыдущего ответа 🙂

    Может быть:

     subdict=dict([(x,bigdict[x]) for x in ['l', 'm', 'n']]) 

    Python 3 поддерживает также:

     subdict={a:bigdict[a] for a in ['l','m','n']} 

    Обратите внимание, что вы можете проверить наличие в словаре следующим образом:

     subdict=dict([(x,bigdict[x]) for x in ['l', 'm', 'n'] if x in bigdict]) 

    соответственно для python 3

     subdict={a:bigdict[a] for a in ['l','m','n'] if a in bigdict} 

    Ладно, это то, что беспокоило меня несколько раз, так что спасибо Джайшу за это.

    Ответы выше выглядят как хорошее решение, как любое, но если вы используете это по всему вашему коду, имеет смысл обернуть функциональность IMHO. Кроме того, здесь есть два возможных варианта использования: один, где вас беспокоит, находятся ли все ключевые слова в оригинальном словаре. и тот, где вы этого не делаете. Было бы неплохо относиться к ним одинаково.

    Итак, для моей двухпенсовой стоимости я предлагаю написать подкласс класса, например,

     class my_dict(dict): def subdict(self, keywords, fragile=False): d = {} for k in keywords: try: d[k] = self[k] except KeyError: if fragile: raise return d 

    Теперь вы можете вытащить суб-словарь с помощью

     orig_dict.subdict(keywords) 

    Примеры использования:

     # ## our keywords are letters of the alphabet keywords = 'abcdefghijklmnopqrstuvwxyz' # ## our dictionary maps letters to their index d = my_dict([(k,i) for i,k in enumerate(keywords)]) print('Original dictionary:\n%r\n\n' % (d,)) # ## constructing a sub-dictionary with good keywords oddkeywords = keywords[::2] subd = d.subdict(oddkeywords) print('Dictionary from odd numbered keys:\n%r\n\n' % (subd,)) # ## constructing a sub-dictionary with mixture of good and bad keywords somebadkeywords = keywords[1::2] + 'A' try: subd2 = d.subdict(somebadkeywords) print("We shouldn't see this message") except KeyError: print("subd2 construction fails:") print("\toriginal dictionary doesn't contain some keys\n\n") # ## Trying again with fragile set to false try: subd3 = d.subdict(somebadkeywords, fragile=False) print('Dictionary constructed using some bad keys:\n%r\n\n' % (subd3,)) except KeyError: print("We shouldn't see this message") 

    Если вы запустите весь вышеуказанный код, вы должны увидеть (что-то вроде) следующий результат (извините за форматирование):

    Исходный словарь:
    {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, ' h ': 7,' k ': 10,' j ': 9,' m ': 12,' l ': 11,' o ': 14,' n ': 13,' q ': 16,' p ' : 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23 , 'z': 25}

    Словарь с нечетными номерами:
    {'a': 0, 'c': 2, 'e': 4, 'g': 6, 'i': 8, 'k': 10, 'm': 12, 'o': 14, ' q ': 16,' s ': 18,' u ': 20,' w ': 22,' y ': 24}

    Не удалось построить subd2:
    оригинальный словарь не содержит некоторых ключей

    Словарь, построенный с использованием некорректных ключей:
    {'b': 1, 'd': 3, 'f': 5, 'h': 7, 'j': 9, 'l': 11, 'n': 13, 'p': 15, ' r ': 17,' t ': 19,' v ': 21,' x ': 23,' z ': 25}

    Еще один (я предпочитаю ответ Марка Лонгэйра)

     di = {'a':1,'b':2,'c':3} req = ['a','c','w'] dict([i for i in di.iteritems() if i[0] in di and i[0] in req]) 
    Python - лучший язык программирования в мире.