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.
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}
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}
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}
This should solve your problem:
>>> dict((k, d.get(k, 0)) for k in s)
{'a': 0, 'c': 0, 'b': 5}
Related
I have a dictionary contains lists of values and a list:
dict={'first':45, 'second':30, 'third':56}
list= [30,45]
I want to compare the value in the dictionary with the list and a match to add to a new dictionary after that, remove from the old dict all the values that are in the new dict: I'm doing something like this:
def get_sessions(self, talks):
result_sessions = {}
for k, v in self.sessions.items():
for i in talks:
if v == i:
result_sessions[k] = v
for k, v in result_sessions.items():
del self.sessions[k]
return result_sessions
Maybe you know a more elegant solution? any help?
This is one approach.
Ex:
d ={'first':45, 'second':30, 'third':56}
lst = [30,45]
result_sessions = {k: v for k, v in d.items() if v in lst}
d = { k : d[k] for k in set(d) - set(result_sessions) }
print(result_sessions)
print(d)
Output:
{'second': 30, 'first': 45}
{'third': 56}
In Python, how to iterate a dict and increment values of each key?
D = {k1:1, k2:2}
I want D to be {k1:2, k2:3}.
You can use a dict comprehension to increment each value, then assign it back
>>> {k: v+1 for k,v in D.items()}
{'k1': 2, 'k2': 3}
You can either modify (also called "mutate") the dictionary D:
for k in D.keys():
D[k] = D[k] + 1
Or you can create a new dictionary and re-assign D to it:
D = { k: v+1 for k, v in D.items() }
The difference will become apparent if something else points at D, or if D is very large and takes longer to re-create than to update in-place.
D = {"k1":1, "k2":2}
for i in D:
D[i] += 1
print(D)
Seems to do the trick, I wasnt sure on the k1 / k2 so i made them strings for testing
I have another solution for you, I hope it is useful.
for key in D:
D[key] +=1
I'd like to use dict comprehensions and the ternary operator to create a new dict. Here is a MWE.
# Step 1: Create a dict, `d`
# {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j'}
import string
d = {k : v for k, v in zip(range(1, 11), string.ascii_lowercase[:10])}
# Step 2: Use dict comprehensions and the ternary operator to get a new dict
new_dict = {k : v if k<5 else v : k for k, v in d.items()}
but encounter this issue,
new_dict = {k : v if k<5 else v : k for k, v in d.items()}
^
SyntaxError: invalid syntax
Why is SyntaxError rasied? How to fix it?
The key:value syntax is not a real expression, so you can't use the ternary operator on it. You need to do the ternary operation separately on the key and value parts:
new_dict = {(k if k<5 else v) : (v if k<5 else k) for k, v in d.items()}
(I changed you test to k<5 rather than v<5, assuming you want to compare the numerical keys to 5; comparing the string values to 5 won't work in Python 3 and will give meaningless results in Python 2.)
This is the correct syntax.
new_dict = {k if k < 5 else v : v if k < 5 else k for k, v in d.items()}
I have a dictionary, and I want to iterate over the keys, test the keys, and then print the keys that pass the test.
For example, my code looks like this at the moment:
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for t in x:
if t > 2:
print t
However, all the output is, is just the key.
How do I get the code to print out the value at the end of the code, instead of the key?
Also, how do I get this in the form of a dictionary, {key : value}?
You could try this: print t, x[t]
Or this:
for key, val in x.items():
if key > 2:
print key, val
If you want to get only the pairs that you're printing into a new dictionary, then you have to put them there:
newdict = {}
for key, val in x.items():
if key > 2:
print key, val
# put all the keys > 2 into the new dict
newdict[key] = val
Of course that solution is printing when it inserts. If you're doing more than just a little script you will get more utility out of breaking functionality out, making sure that any given function does one, and only one, thing:
def filter_dict(x):
newdict = {}
for key, val in x.items():
if key > 2:
# put all the keys > 2 into the new dict
newdict[key] = val
def pretty_print(dct):
for k, v in dct.items():
print k, v
filtered = filter_dict(x)
pretty_print(dct)
This doesn't apply if you're just debugging, of course, and there are ways in which it depends on how large of a program you're writing: if you're doing a simple enough thing then the extra flexibility you get by breaking functionality up is lost because of the extra effort of figuring out exactly what any given thing does. That said: you should generally do it.
Additionally, the most idiomatic way to filter lists on a simple comparison in Python is to use a dict comprehension (new in Python 2.7/3.0):
filtered = {key: val for key, val in x if key > 2}
print [(k,v) for k,v in yourDict.items() if test(k)]
(You could just do k for k,v in... or v for k,v in.... If you only need values, you can use yourDict.values().)
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for t in x:
if t > 2:
print '{}: {}'.format(t, x[t])
Slightly more pythonic:
>>> for key, value in x.iteritems():
... if key > 2:
... print '{}: {}'.format(key, value)
...
4: a
9: d
edit: To just print the value:
>>> for key, value in x.iteritems():
... if key > 2:
... print value
...
a
d
key as well as value:
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for k,v in x.items():
if k>2: print"{%d : %s}"%(k,repr(v))
{4 : 'a'}
{9 : 'd'}
just value:
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for k,v in x.items():
if k>2:print v
a
d
Just the keys:
>>> [k for k in x.iterkeys() if k > 2]
[4, 9]
Just the values:
>>> [v for k,v in x.iteritems() if k > 2]
['a', 'd']
Key-value pairs:
>>> [(k, v) for k,v in x.iteritems() if k > 2]
[(4, 'a'), (9, 'd')]
As a dict:
>>> dict((k,v) for k,v in x.iteritems() if k > 2)
{9: 'd', 4: 'a'}
If you want to create a dictionary with subset of items, you can also use a dictionary comprehension for Python 2.7+:
>>> x = {4:"a", 1:"b", 0:"c", 9:"d"}
>>> y = {k:v for k, v in x.iteritems() if k > 2}
>>> y
{9: 'd', 4: 'a'}
This is only a newer equivalent with only minor syntax differences for what Johnysweb shows in his answer:
>>> y = dict((k, v) for k, v in x.iteritems() if k > 2)
>>> y
{9: 'd', 4: 'a'}
The following list comprehension will print the key and value if key > 2.
Try this:
print [(key, value) for key, value in x.iteritems() if key > 2]
This solution prints the key t and the value in the dictionary x at key t.
x = {4:"a", 1:"b", 0:"c", 9:"d"}
for t in x:
if t > 2:
print t, x[t]
Using lambda function
(lambda x:[(k,v) for k,v in x.iteritems() if k > 2])(x)
Given two dictionaries, d1 and d2, and an integer l, I want to find all keys k in d1 such that either d2[k]<l or k not in l. I want to output the keys and the corresponding values in d2, except if d2 does not contain the key, I want to print 0. For instance, if d1 is
a: 1
b: 1
c: 1
d: 1
and d2 is
a: 90
b: 89
x: 45
d: 90
and l is 90, the output would be (possibly in a different order)
b 89
c 0
What is the best way to do this in Python? I am just starting to learn the language, and so far this is what I have:
for k in d1.keys():
if k not in d2:
print k, 0
else:
if d2[k]<l:
print k, d2[k]
This works of course (unless I have a typo), but it seems to me that there would be a more pythonic way of doing it.
Yours is actually fine -- you could simplify it to
for k in d1:
if d2.get(k, 0) < l:
print k, d2.get(k, 0)
which is (to me) pythonic, and is pretty much a direct "translation" into code of your description.
If you want to avoid the double lookup, you could do
for k in d1:
val = d2.get(k, 0)
if val < l:
print k, val
You can simplify this by using a defaultdict. Calling __getitem__ on a defaultdict will return the "default" value.
from collections import defaultdict
d = defaultdict(int)
print d['this key does not exist'] # will print 0
Another bit that you could change is not to call keys. The dictionary implements iter. It would be preferable to simply write:
for k in d1:
Here is a compact version, but yours is perfectly OK:
from collections import defaultdict
d1 = {'a': 1, 'b': 1, 'c': 1, 'd': 1}
d2 = {'a': 90, 'b': 89, 'x': 45, 'd': 90}
l = 90
# The default (==0) is a substitute for the condition "not in d2"
# As daniel suggested, it would be better if d2 itself was a defaultdict
d3 = defaultdict(int, d2)
print [ (k, d3[k]) for k in d1 if d3[k] < l ]
Output:
[('c', 0), ('b', 89)]
Yours is good enough but here's one that is a little simpler:
for k in d1:
val = d2.get(k, 0)
if val < l:
print k, val