2015-02-16 4 views
0

У меня есть словарь:Условный список из словаря против Поиска словаря с условием - Python

d = {'red':1,'green':2,'blue':3} 

Я позволил создать список ключей из этого словаря, которые соответствуют условию, используя следующий синтаксис :

mylist = [k for k in d if d[k] > 1] 
print mylist 

>>>> ['blue', 'green'] 

Но если я пытаюсь искать через словарь с условием, используя аналогичную строку кода, это не работает:

for k in d if d[k] > 1: 
    print k, d[k] 

>>>>for k in d if d[k] > 1: 
         ^
SyntaxError: invalid syntax 

Может ли кто-нибудь объяснить мне, почему это не так? Или если я что-то делаю неправильно? Похоже, если мне удастся совместить просмотр словаря с условным выражением при составлении списка, мне также должно быть позволено делать это при просмотре словаря без составления списка.

Я работаю в Python 2.7.8

ответ

2

Вместо:

for k in d if d[k] > 1: 
    print k, d[k] 

Вы должны просто писать:

for k in d: 
    if d[k] > 1: 
     print k, d[k] 

Список постижение синтаксис, который ставит все на одну [k for k in d if d[k] > 1] линия - это просто синтаксический сахар для вышеуказанного.

Редактировать: Хотя, как я уже упоминал в комментариях ниже, вы можете сделать что-то сложное с пониманием генератора. Понимание генератора, если кто-либо, кто читает этот ответ позже, не знает, похоже на понимание списка, но он создает генератор , итерируемый объект, который вы можете вставить в цикл for (или вставить в переменную для более поздняя обработка). Так что вы можете сделать:

g = (k for k in d if d[k] > 1) 

и позже,

for k in g: 
    print k, d[k] 

Или, объединены в одну операцию (хотя это немного некрасиво):

for k in (x for x in d if d[x] > 1): 
    print k, d[k] 

Обратите внимание, что x внутри понимания генератора могло быть и k, но я решил использовать другое имя, чтобы было ясно, что происходит. Название x является не в области действия за пределами понимания, кстати:

for k in (x for x in d if d[x] > 1): 
    print k, d[k], x 

производит:

Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
NameError: name 'x' is not defined 

Как я уже сказал, что это немного некрасиво, так как вы в конечном итоге приходится писать for дважды. (Один раз для кода «что делает генератор» и один раз для кода «Я хочу развернуть генератор и получить его результаты»). Но это ближе всего к синтаксису «Я хочу сделать это в одной строке», который вы ищете.

+0

Я понимаю, что я могу написать это в двух строки - как вы сказали - но почему я не могу записать это в одной строке, как я могу при создании списка? – spacetyper

+0

@spacetyper - Просто потому, что ни один синтаксический сахар никогда не был создан для интересующего вас случая, и ни один из разработчиков Python даже не захотел создать такой синтаксический сахар. Это всего лишь списки, в которых синтаксический сахар считался необходимым. – rmunn

+0

@spacetyper - Вы можете сделать что-то сложное с пониманием генератора, если вы действительно хотите его на одной строке, но он уродлив и умаляет читаемость. Однако, ради полноты, я добавлю его к моему ответу (он не будет хорошо размещен в комментарии). – rmunn

0

В первом случае это понимание списка. Второй случай - ничто.

1

Я согласен с @rmunn. Если вы, однако, настаиваете на одной строке, то это будет работать:

d = {'red':1,'green':2,'blue':3} 
for k, v in ((k, v) for (k, v) in d.items() if v > 1): 
    print k, v 

Это только поиск в словаре. Если вы пойдете на решение, предоставленное @rmunn, я бы уменьшил поиск словарей до одного.

for k, v in d.items(): 
    if v > 1: 
     print k, v 

Как отметил @rmunn в комментариях еще лучше использовать ленивый iteritems() в Python 2, который возвращает итератор:

for k, v in d.iteritems(): 
    if v > 1: 
     print k, v 
+1

'd.iteritems()' может быть еще лучше, поскольку OP использует Python 2.x. Его пример - крошечный словарь, но если у него есть большой словарь в его реальном коде, ему будет намного лучше с 'iteritems()', так как он не будет создавать весь список ключей/значений в памяти все сразу. Но +1 для предложения 'd.items()' в первую очередь. – rmunn

+0

@rmunn Да, человек! Вы совершенно правы! Я еще не сделал Python 2. Я отредактирую ответ. –

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