2015-05-15 3 views
2
Dict = {'w1': 56, 'w2': 19, 'w3': 77, 'w4': 45, 'w5': 31} 
myWords = ['w1','w4','w5'] 

OutputList=[] 
for items in myWords: 
    tmps = Dict[items] 
    OutputList.append(tmps) 

Моего вопросом мы может, без используя for петли, собрать значение (выход) из словаря с определенным списком («MyWord»)?Сбор значения из словаря Python со списком ключей

+2

Почему вы хотите, чтобы избежать использования для цикла? – Shashank

+10

** Не используйте ** переменные с именем верхнего регистра! ** Не ** повторно использовать имя встроенных модулей только с измененной капитализацией! – kay

+21

Не знаете, как вам это удалось, но похоже, что вы обнаружили ошибку. Обычно вы не можете отмечать более одного ответа как «принятого» (вы должны выбрать тот, который вам больше всего помог). И все же мы здесь, с двумя ответами, отмеченными как принятые. См. [Как этот вопрос получил два принятых ответа?] (Https://meta.stackoverflow.com/q/294342) –

ответ

7

Вы можете использовать список понимание:

OutputList = [Dict[x] for x in myWords] 
+0

Является ('' '' for'' '), неявный в понимании? – wwii

+0

Да, в любом случае вам нужно перебирать список, в Python, если это возможно, лучше использовать карту и встроенные функции при итерации, потому что они реализованы в C – Javier

+1

@wwii: Просто потому, что синтаксис понимания списка включает в себя ключевое слово 'for ', не означает, что это« цикл ». –

3

или использовать карту, если myWords содержит ключи словаря Dict, чтобы использовать

OutputList = map(Dict.get, myWords) 
+0

Привет, Хосе. Если dict большой, то len (Dict.keys()) = 1048576, а мой список около 10000, поэтому функция карты может улучшить производительность при сравнении с циклом For? –

+0

@GregHewgill вы можете мне помочь с этим вопросом, потому что я не знаю –

+0

@ChinLim, попробуйте его и посмотрите - [timeit] (https://docs.python.org/3/library/timeit.html) – wwii

2
l = ['a', 'b', 'c'] 
d = { 'a': 1, 'b': 2} 
result = map(lambda x: d[x], filter(d.get, l)) 
print result #[1, 2] 
+0

Привет Хавьер. Благодарю. Что означает «lamda x: d [x]» в приведенном выше примере? В файле справки python карта (функция, последовательность), это предложение может работать с огромным словарем и большим списком .. Thanjs –

+0

не могли бы вы объяснить, почему голосование? Это ответ на вопрос, с другим подходом – Javier

+0

Вы пытаетесь получить значения словаря, Map будет циклически перебирать результат фильтра и будет возвращать список с первым параметром (лямбда-функцией), применяемым для каждого элемента в результате в фильтре. Попробуйте это в оболочке Python, это даст то, что вы ожидаете – Javier

19

Это то, что operator.itemgetter является для:

>>> import operator 
>>> Dict = {'w1': 56, 'w2': 19, 'w3': 77, 'w4': 45, 'w5': 31} 
>>> myWords = ['w1','w4','w5'] 
>>> operator.itemgetter(*myWords)(Dict) 
[56, 45, 31] 
+0

Привет, Чепнер. Если dict большой, то len (Dict.keys()) = 1048576, а мой список - около 10000, поэтому operator.itemgetter может улучшить производительность при сравнении с циклом For? –

+0

Вам нужно было бы протестировать его, но я думаю, что 'itemgetter' должен быть быстрее. – chepner

+0

Эй, чепнер, хороший ответ. Однако небольшое предложение .. Добавьте ссылку на [docs] (https://docs.python.org/2/library/operator.html#operator.itemgetter), так как это действительно поможет тем, кто не знает о 'operator.itemgetter' –

5

Вот тесты нескольких различных методов:

from __future__ import print_function 
import timeit 
from operator import itemgetter 

def f1(d, l): 
    '''map''' 
    return list(map(d.get, l)) 

def f2(d, l): 
    '''itemgetter''' 
    return itemgetter(*l)(d) 

def f3(d, l): 
    '''list comprehension''' 
    return [d[k] for k in l] 

def f4(d, l): 
    '''WRONG, but map and filter''' 
    return list(map(lambda k: d[k], filter(d.get, l))) 

def f5(d, l): 
    '''simple for loop''' 
    rtr=[] 
    for e in l: 
     rtr.append(d[e]) 
    return rtr 

def f6(d, l): 
    '''CORRECTED map, filter '''  
    return list(map(lambda k: d[k], filter(d.__contains__, l))) 

if __name__ == '__main__': 
    s=10000000 
    d={'W{}'.format(k):k for k in range(s)} 
    l=['W{}'.format(x) for x in range(0,s,4)] 

    times=[]     
    for f in (f1,f2,f3,f4,f5,f6): 
     times.append((f.__doc__, timeit.timeit('f(d,l)', setup="from __main__ import f, d, l", number=10))) 

    for e in sorted(times, key=itemgetter(1)): 
     print('{:30}{:10.3f} seconds'.format(*e)) 

Для Python 2.7, печатает:

itemgetter       4.109 seconds 
list comprehension     4.467 seconds 
map        5.450 seconds 
simple for loop     6.132 seconds 
CORRECTED map, filter    11.283 seconds 
WRONG, but map and filter   11.852 seconds 

Python 3.4:

itemgetter       5.196 seconds 
list comprehension     5.224 seconds 
map        5.923 seconds 
simple for loop     6.548 seconds 
WRONG, but map and filter   9.080 seconds 
CORRECTED map, filter    9.931 seconds 

PyPy:

list comprehension     4.450 seconds 
map        4.718 seconds 
simple for loop     5.962 seconds 
itemgetter       7.952 seconds 
WRONG, but map and filter   8.962 seconds 
CORRECTED map, filter    9.909 seconds 

Вы можете видеть, что даже со словарем аналогичного размера (1 000 000 элементов), что означает OP, что простой цикл «для» является конкурентоспособным с более удобными методами. Понимание списка очень конкурентоспособно.

Вы также можете увидеть, что что-то, что выглядит фантазией, не так уж велико.

преждевременная оптимизация есть корень всех зол

+1

Интересно, что 'itemgetter' на самом деле * хуже * в PyPy, а не просто менее оптимизирован. – chepner

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