2013-07-02 3 views
1

У меня есть словарь список, как показано ниже:Как получить доступ к списку, содержащему определенный элемент в словаре?

dict = {'key1':list1, 'key2':list2} 

и

list1=['a', 'b', 'c'] 
list2=['d', 'e', 'f'] 

т.е.

dict = {'key1': ['a', 'b', 'c'], 'key2': ['d', 'e', 'f']} 

Я хотел бы получить объект списка, содержащего 'B', то есть list1, используя карту, а не используя явный цикл for. Я много гугл, но не могу найти информацию. Любая помощь будет оценена.

+2

В качестве побочного примечания, это плохая идея вызвать словарь 'dict'. Как только вы это сделаете, вы больше не сможете обращаться к встроенному типу и конструктору с тем же именем. – abarnert

ответ

2

Нет никакого способа сделать это без явного или неявного цикла.

То есть, вы можете сделать одно из них:

key = next(lst for lst in d.values() if 'b' in lst) 

Но в любом случае, это действительно делает то же самое для цикла делает. В частности, это примерно то же самое:

for lst in d.values(): 
    if 'b' in lst: 
     key = let 
     break 

... это, вероятно, именно цикл, который вы собираетесь писать.


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

Например, давайте создадим карту от каждого члена списка в списке он находится в:

valmap = {val:lst for lst in d.values() for val in lst} 

Теперь, каждый раз, когда вы хотите узнать, какой список 'b' находится, просто сделать это:

valmap['b'] 

Из вашего вопроса, вы, возможно, спрашивали об использовании map. Во-первых, map по-прежнему представляет собой неявный цикл for. Во-вторых, map действительно не дает вам никакого способа делать то, что вы хотите; вы можете использовать его, например, создать новую последовательность с True вместо списка, содержащего 'b', и False везде, но вам все равно придется искать эту последовательность, чтобы найти True. Здесь вы найдете filter. Вы можете написать genexpr решение выше, как:

key = next(filter(lambda lst: 'b' in lst, d.values())) 

И это в значительной степени точно то же самое, как genexpr. (В CPython это, вероятно, немного быстрее, чем явный цикл и немного медленнее, чем genexpr, но это также, вероятно, не имеет значения.)

+0

+1 для, 'Нет никакого способа сделать это без явного или неявного цикла.' – John

+0

@johnthexiii: На самом деле, мне не очень нравится то, как я это написал. Цикл for в genexpr/comp довольно явный - он даже записан так же, как и в заявлении. Но я не уверен, как еще сделать различие новичком-дружелюбием ... – abarnert

0
next(x for x in D.itervalues() if 'b' in x) 
0

Вы используете неправильную структуру данных, если вам нужно посмотреть вещи по такой ценности. Для этого вы должны построить inverted index, который отображает значения в соответствующие им ключи. (Вы можете построить этот инвертированный индекс вверх по мере создания своего словаря.) После того, как у вас есть этот ключ, вы можете легко найти содержащийся список в оригинальном словаре.Если по каким-то причинам вы не можете создать перевернутый индекс, как вы строите словарь (возможно потому, что вы не строить его, это просто доставлено к вам), вы можете построить инвертированный индекс, как это:

inverted_index = {v : k for k, l in d.items() for v in l} 

Здесь я использую d для имени вашего словаря вместо dict, так как dict - это имя встроенного типа, который вы никогда не должны скрывать.

+0

Во-первых, его значения dict - это списки, поэтому это не сработает. (Вы не можете использовать список в качестве ключа dict.) И даже если бы это сработало, это не решило бы его проблему, которая должна выглядеть в любом элементе каждого списка, а не в самом списке , – abarnert

+0

@abamert: Нет. Если вы введете эти строки в интерактивный режим '>>> d = {'key1': ['a', 'b', 'c'], 'key2': ['d', 'e', ​​'f'] } >>> inverted_index = {v: k для k, l в d.items() для v в l} >>> print inverted_index' вы увидите вывод '{'a': 'key1', ' b ':' key1 ',' c ':' key1 ',' d ':' key2 ',' e ':' key2 ',' f ':' key2 '} ', который затем позволяет вам искать ключ через' >>> inverted_index ['b'] ', который будет генерировать' key1' и список через '>>> d [inverted_index ['b']]', который будет генерировать '['a', 'b', 'c' ] '. То есть, точно, что он хотел. Таким образом, он * работает *, и он * делает * решает свою проблему. – jason

+0

К сожалению, в конце я не видел дополнительных 'for v in l'. Ты прав. Но он по-прежнему отображается на клавиши, а не на списки, которые он просил, поэтому вам нужен дополнительный шаг 'd [inverted_index ['b']]' вместо просто 'inverted_dict ['b']'. Если он действительно нуждается в ключах, это преимущество; если он этого не делает, это просто лишняя сложность без причины. – abarnert

Смежные вопросы