2

I have a set and dictionary and a value = 5

v = s = {'a', 'b', 'c'}
d = {'b':5 //<--new value}

If the key 'b' in dictionary d for example is in set s then I want to make that value equal to the new value when I return a dict comprehension or 0 if the key in set s is not in the dictionary d. So this is my code to do it where s['b'] = 5 and my new dictionary is is ...

{'a':0, 'b':5, 'c':0}

I wrote a dict comprehension

{  k:d[k] if k in d else k:0 for k in s}
                          ^
SyntaxError: invalid syntax

Why?! Im so furious it doesnt work. This is how you do if else in python isnt it??

So sorry everyone. For those who visited this page I originally put { k:d[k] if k in v else k:0 for k in v} and s['b'] = 5 was just a representation that the new dictionary i created would have a key 'b' equaling 5, but it isnt correct cus you cant iterate a set like that.

So to reiterate v and s are equal. They just mean vector and set.

vaultah
  • 44,105
  • 12
  • 114
  • 143
Leon
  • 5,701
  • 3
  • 38
  • 38
  • 1
    Your description is very confused. If `s` is a set, `s['b']` doesn't make any sense. Also, what is `v` supposed to be? Is it `s`? Or something different? – abarnert Jul 15 '13 at 22:23
  • Sorry it is v is supposed to be s. Im doing python vector homework – Leon Jul 15 '13 at 22:31

4 Answers4

11

The expanded form of what you're trying to achieve is

a = {}
for k in v:
    a[k] = d[k] if k in d else 0

where d[k] if k in d else 0 is the Python's version of ternary operator. See? You need to drop k: from the right part of the expression:

{k: d[k] if k in d else 0 for k in v} # ≡ {k: (d[k] if k in d else 0) for k in v}

You can write it concisely like

a = {k: d.get(k, 0) for k in d}
vaultah
  • 44,105
  • 12
  • 114
  • 143
3

You can't use a ternary if expression for a name:value pair, because a name:value pair isn't a value.

You can use an if expression for the value or key separately, which seems to be exactly what you want here:

{k: (d[k] if k in v else 0) for k in v}

However, this is kind of silly. You're doing for k in v, so every k is in v by definition. Maybe you wanted this:

{k: (d[k] if k in v else 0) for k in d}
abarnert
  • 354,177
  • 51
  • 601
  • 671
  • This only seems to return me the original dictionary – Leon Jul 15 '13 at 22:47
  • 1
    @Leon: Yes, as I explained, "this is kind of silly. You're doing `for k in v`, so every `k` is in `v` by definition." This does exactly what you were trying to do in your question, which is probably not what you wanted to do, but it's hard to guess what you wanted to do without reading your mind. – abarnert Jul 15 '13 at 22:57
3
In [82]: s = {'a', 'b', 'c'}

In [83]: d = {'b':5 }

In [85]: {key: d.get(key, 0) for key in s}
Out[85]: {'a': 0, 'b': 5, 'c': 0}
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Not what he wants. He's checking `k in v`, not `k in d`. And there would be no reason to do any check if `v` and `k` were the same dict, because then `key` would always be present. – abarnert Jul 15 '13 at 22:22
3

This should solve your problem:

>>> dict((k, d.get(k, 0)) for k in s)
{'a': 0, 'c': 0, 'b': 5}
Conan Li
  • 474
  • 2
  • 6