фильтровать элементы в словаре python, где ключи содержат определенную строку

Я кодер C, развивающий что-то в python. Я знаю, как сделать следующее в C (и, следовательно, в C-подобной логике, применяемой к python), но мне интересно, что такое «Python».

У меня есть словарь d, и я бы хотел работать с подмножеством элементов, только те, у кого есть ключ (строка), содержат определенную подстроку.

т.е. логика C будет:

for key in d: if filter_string in key: # do something else # do nothing, continue 

Я предполагаю, что версия python будет чем-то вроде

 filtered_dict = crazy_python_syntax(d, substring) for key,value in filtered_dict.iteritems(): # do something 

Я нашел много сообщений о фильтрационных словарях, но не смог найти тот, который был именно таким.

Мой словарь не вложен, и я использую python 2.7

4 Solutions collect form web for “фильтровать элементы в словаре python, где ключи содержат определенную строку”

Как насчет понимания диктата :

 filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k} 

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

Для этого синтаксиса требуется Python 2.7 или выше.

В Python 3 есть только dict.items() , а не iteritems() поэтому вы должны использовать:

 filtered_dict = {k:v for (k,v) in d.items() if filter_string in k} 

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

 for key, val in d.iteritems(): if filter_string not in key: continue # do something 

Однако, если вы realllly хотите что-то позволить вам итерации через фильтрованный dict, то я бы не сделал двухэтапный процесс построения фильтрованного dict, а затем итерации через него, но вместо этого использовал генератор, потому что более pythonic (и удивительный), чем генератор?

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

 # The implementation of my generator may look vaguely familiar, no? def filter_dict(d, filter_string): for key, val in d.iteritems(): if filter_string not in key: continue yield key, val 

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

 for key, val in filter_dict(d, some_string): # do something 

Короче: генераторы являются удивительными.

 input = {"A":"a", "B":"b", "C":"c"} output = {k:v for (k,v) in input.items() if key_satifies_condition(k)} 

Джонатан дал вам подход, используя в своих ответах подталкивание . Вот такой подход, который касается вашего дела .

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

Я использую iteritems( ), так как вы отметили свой вопрос с помощью python-2.7

 results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k]) 

Теперь результат будет в списке с some_function применяемым к каждой паре ключей / значений словаря, которая имеет foo в своем ключе.

Если вы просто хотите иметь дело со значениями и игнорировать ключи, просто измените понимание списка:

 results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k]) 

some_function может быть любым вызываемым, поэтому лямбда будет работать также:

 results = map(lambda x: x*2, [v for k,v in a_dict.iteritems() if 'foo' in k]) 

Внутренний список на самом деле не требуется, поскольку вы также можете передать выражение генератора для отображения:

 >>> map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2)) [4] 
Python - лучший язык программирования в мире.