2015-10-05 2 views
0

У меня есть defaultdict, Python 3.4, объект похож на:Как фильтровать этот python defaultdict по значению внутри dict?

mydefaultdict = defaultdict(dict) 
mydefaultdict['name1']['filename'] = 'name1' 
mydefaultdict['name1']['records_available'] = True 
mydefaultdict['name2']['filename'] = 'name2' 
mydefaultdict['name2']['records_available'] = False 

Я хочу создать отфильтрованное подмножество только тех, с records_available = True. До сих пор у меня есть понимание диктата, которое делает:

defaultdict(dict, {k: v['records_available'] for k, v 
       in mydefaultdict.items() }) 

которое действительно близко. Но я не уверен, как реализовать фильтр. Если бы это был базовый диктофон, то работала бы такая работа.

defaultdict(dict, {k: v['records_available'] for k, v 
       in mydefaultdict.items() if v == True }) 

мне удалось сделать это с помощью вложенного цикла for, if. Но я так близко подошел к пониманию диктатора, я задаюсь вопросом, может ли кто-то решить это решение. Разбор python-коллекций - это ежедневная работа для меня.

Мое текущее решение:

for i in audio_files.values(): 
    if i['records_available']: 
     filterd_files[i['filename']] = i 

Edit: user3100115 правильно. Данные с заданными данными не возвращают одну запись с ответом user31000115.

+5

'{k: v для k, v в файле mydefaultdict.items(), если v ['records_available'] == True}' – styvane

+1

@ user3100115: почему вы не опубликовали это как ответ? –

+0

user3100115 Оказывается, я очень устал и использовал именно код, который я наклеил выше. Как вы заметите, мои фиктивные записи являются «ложными». Я на самом деле попробовал очень похожую версию вашего решения и, конечно же, получил нулевые записи. Спасибо за то, что подтвердили мое здравомыслие и заставили меня почувствовать себя застенчивым. ;) – gonzo

ответ

0

Похоже, что вы хотите получить v['records_available'] как значение (для всего, что это значение истинно). Но то, что вы, вероятно, хотите посмотреть, это тот случай, когда значения не имеют элемента 'records_available' или вовсе не словарь. Первый можно решить, используя метод .get, но если вы хотите защитить вас от последнего, вы должны определить свой собственный getitem (аналогично getattr), который вернет default, когда объект либо не поддерживает подписку вообще, либо не содержит требуемый пункт:

def getitem(obj, key, default=None): 
    try: 
     return obj[key] 
    except (AttributeError, KeyError): 
     return default 

Тогда вы просто использовать это в качестве фильтра (я использую func(v) преобразовать значение, какое значение вы хотите, так как я думаю, собирается для "records_available" пункта не имеет смысла - это будет только до True):

{k, func(v) for k, v in mydefaultdict.items() if getitem(v, "records_available") == True)} 

Обратите внимание, что getitem будет возвращать None всякий раз, когда v не содержит "records_available" или вообще не поддерживает подписку, а затем, следовательно, эта пара ключей и значений не войдет в словарь.