5

There is a dict,

dlist = [{'Bilbo' : 'Ian', 'Frodo' : 'Elijah'}, {'Bilbo' : 'Martin', 'Thorin' : 'Richard'}]

And let k = 'Frodo'

I want to extract the value corresponding to k when it exists and make a list.

I wrote

value_list = [dlist[i][k] for i in range(len(dlist)) if k in dlist[i] else "NOT PRESENT"]. 

But computer says else is wrong. I don't know why.

cphlewis
  • 15,759
  • 4
  • 46
  • 55
Jiho Baek
  • 183
  • 1
  • 7

2 Answers2

7

When you have else part in the list comprehension , bring it before the for loop , Example -

value_list = [dlist[i][k] if k in dlist[i] else "NOT PRESENT" for i in range(len(dlist))]
value_list
>>> ['Elijah', 'NOT PRESENT']
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
6

if after the for in a list comprehension is for filtering the list: when the condition is false you get no element at all.

if..else before the list comprehension is simply a ternary operator, no different than in any other expression.

A couple of other points: for i in range(len(...)) is almost always wrong in Python. If you are only iterating over a single list just iterate over that. Also, dictionaries have a method .get() that you can use to avoid the if altogether. So:

value_list = [d.get(k, "NOT PRESENT") for d in dlist]

or if you prefer the if:

value_list = [d[k] if k in d else "NOT PRESENT" for d in dlist]
Duncan
  • 92,073
  • 11
  • 122
  • 156
  • Thank you for answering. But why is "for i in range(len(...))" wrong for iterating a single list in python? and what is the meaning of "iterate over that"? – Jiho Baek Jul 15 '15 at 08:20
  • @JihoBaek They meant that you can rewrite `dlist[i][k] for i in range(len(dlist))` to just be `d[k] for d in dlist`, since `d` will refer to each element of the list as it iterates, rather than using `i` as an index. – SuperBiasedMan Jul 15 '15 at 08:55
  • @SuperBiasedMan oh! I get it!! Thanks – Jiho Baek Jul 15 '15 at 10:57