Python a list and a dictionary - python

I have a list (x) and a dictionary (d)
x=[1,3,5]
d={1:a,2:b,3:c,4:d,5:e}
As you can see a few variables match a few keys in the dictionary
But how can I print only the values whose key matches a variable in the list?
I tried a for loop but it returns only the key. Thanks for any assistance!

Something like this?
for key in d:
if key in x:
print d[key]
This will loop through every key in the dictionary, and if the key appears in x then it will print the value of x.

try like this:
>>> x=[1,3,5]
>>> d={1:'a',2:'b',3:'c',4:'d',5:'e'}
>>> for key in d.keys():
... if key in x:
... print d[key]
...
a
c
e
or you can use dict.get:
>>> for num in x:
... print d.get(num,"not found")
...
a
c
e
dict.get will give the value of key, if key is found in dictionary else defaultvalue
syntax : dict.get(key[, default])

If you are sure that all of the keys in x are in your dictionary
for key in x:
print(d[key])
Otherwise you can check first
for key in x:
if x in d:
print(d[key])

You can use this one-liner list comprehension:
[d[key] for key in x if key in d]
This will also work if not all items in the list are keys in the dictionary.
for example:
>>> d = {1:'a', 3:'b'}
>>> x = [1, 2]
>>> [d[key] for key in x if key in d]
... ['a']

Related

Why isnt the output showing k1, k2, k3?

I've been trying to learn Python and have come across this issue. I can't figure out how the current output came about.
d={'k1':1,'k2':2,'k3':3}
for key,value in d.keys() :
print(key)
Output:
k
k
k
I expected the output to be:
k1
k2
k3
You are trying to print all key, value pair from your dictionary d. But you are only able to see first character of the key when you try to print key. I will explain you by splitting your for loop for key,value in d.keys().
This is your dictionary, d
d = {'k1':1,'k2':2,'k3':3}
The for loop takes d.keys() and iterates. d.keys() look like this
print(d.keys()) # outputs dict_keys(['k1', 'k2', 'k3'])
for loop iterates over this list of keys ['k1', 'k2', 'k3']
But when you do, this
key,value = 'k1' # this happens with each of the keys in the list
print(key,value) # output k 1
Your key k1 got split into two single character strings k and 1 which can be termed as an unintentional tuple creation #inquisitiveOne and gets assigned to key and value variables respectively.
When you try to print value inside the for loop, you will see 1, 2, 3 but that is in fact the second character of the key attribute and not the value attribute. If you try printing, print(type(value)) you will get to know that it is in fact a string variable and not an integer.
To get the proper value of the key you need to only use a single variable.
d={'k1':1,'k2':2,'k3':3}
for key in d.keys():
print(key)
Output:
k1
k2
k3
As mentioned by #asikorski you can achieve the same using just for key in d: print(key)
If you need to get key, value pairs. Then use d.items()
for key,value in d.items():
print(key,value)
Output:
k1 1
k2 2
k3 3
Hope it helps!
d.keys() returns ['k1', 'k2', 'k3'], but you split that into two parts with key, value, so key=='k', value=='1' the first time, and key=='k', value=='2' the second time, and so on. What you want is:
for key in d.keys():
print(key)
But you can do better and iterate directly over the dictionary without using the .keys() method:
for key in d:
print(key)
Finally, if you need to use both keys and values:
for key, values in d.items():
print(key)
print(value)
d.keys() is a list and it's value will be ["k1", "k2", "k3"]
>> d.keys()
["k1", "k2", "k3"]
When you use for key,value in d.keys(), unpacking will happen on the string value. Which means from "k1", "k" will be assigned to key and "1" will be assigned to value.
Luckily it didn't give error because there were only 2 characters in the string.
>> key, value = "k1"
>> key
k
>> value
1
And, that is the reason it printed k k k in console.!
The right way is to iterate through k.items()
for key,value in d.items():
print(key,value)
Output
k1 1
k2 2
k3 3
d={'k1':1,'k2':2,'k3':3}
for key in d.keys() :
print(key)
Try this code, this should work.
for getting the keys you need the keys API:
d={'k1':1,'k2':2,'k3':3}
for key in d.keys() :
print(key)
for getting the values use the values API:
d={'k1':1,'k2':2,'k3':3}
for value in d.values() :
print(value)
for getting keys and values there is the items API:
d={'k1':1,'k2':2,'k3':3}
for key,value in d.items() :
print(key)
print(value)
hope it helps
Answer is unintentional tuple creation.
In the statement:
for key,value in d.keys() :
you are creating a tuple unintentionally.
>>> key, value = "k1"
>>> key
'k'
>>> value
'1'
Note that the brackets are optional for creating a tuple.
The above is the same as:
>>> (key, value) = "k1"
>>> key
'k'
>>> value
'1'
>>>
Hence the output.
The problem is in your for loop:
for key,value in d.keys() :
d.keys() is an iterable (technically a dict_keys object) that contains only the keys of d: k1, k2, and k3.
Your for loop unpacks each string into k (represented by key) and a number (represented by value). You then print only key, which in each instance is k.
To remedy the issue, simply stop unpacking the keys:
for key in d.keys():

Key with multiple values - check if value is in dictionary python

I have a dictionary that has a list of multiple values stored for each key. I want to check if a given value is in the dictionary, but this doesn't work:
if 'the' in d.values():
print "value in dictionary"
Why doesn't it work with multiple values stored as a list? Is there any other way to test if the value is in the dictionary?
d.values() usually stores the values in list format. So you need to iterate through the list contents and check for the substring the is present or not.
>>> d = {'f':['the', 'foo']}
>>> for i in d.values():
if 'the' in i:
print("value in dictionary")
break
value in dictionary
Your values is a list!
for item in d.values():
if 'the' in item:
print "value in dictionary"
It should be pretty simple:
>>> d = { 'a': ['spam', 'eggs'], 'b': ['foo', 'bar'] }
>>> 'eggs' in d.get('a')
True
You can iterate over the dictionary.
If your dictionary looks like follows:
my_dictionary = { 'names': ['john', 'doe', 'jane'], 'salaries': [100, 200, 300] }
Then you could do the following:
for key in my_dictionary:
for value in my_dictionary[key]:
print value
You can naturally search instead of print. Like this:
for key in my_dictionary:
for value in my_dictionary[key]:
if "keyword" in value:
print "found it!"
There is probably a shorter way to do this, but this should work too.
If you just want to check whether a value is there or not without any need to know the key it belongs to and all, you can go with this:
if 'the' in str(d.values())
Or for a one-liner, you can use the filter function
if filter(lambda x: 'eggs' in x, d.values()) # To just check
filter(lambda x: 'eggs' in d[x] and x, d) # To get all the keys with the value
I like to write
if 0 < len([1 for k in d if 'the' in d[k]]):
# do stuff
or equivalently
if 0 < len([1 for _,v in d.iteritems() if 'the' in v]):
# do stuff

Iterating over dict values

If i would like to iterate over dictionary values that are stored in a tuple.
i need to return the object that hold the "CI" value, i assume that i will need some kind of a for loop :
z = {'x':(123,SE,2,1),'z':(124,CI,1,1)}
for i, k in db.z:
for k in db.z[i]:
if k == 'CI':
return db.z[k]
i am probably missing something here, a point of reference would be good.
if there is a faster way doing so it would all so help greatly
Ways to iterate over a dictionary
First things first, there are a few ways you can loop over a dictionary.
Looping directly over the dictionary:
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> for key in z:
... print key,
...
'x' 'z'
Notice that the loop variables that get returned when you just loop over a dictionary are the keys, not the values associated with those keys.
Looping over the values of a dictionary:
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> for value in z.values(): # Alternatively itervalues() for memory-efficiency (but ugly)
... print value,
...
(123,'SE',2,1) (124,'CI',1,1)
Looping over both the keys and the values:
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> for key, value in z.items(): # Again, iteritems() for memory-efficiency
... print key, value,
...
'x' (123,'SE',2,1) 'z' (124,'CI',1,1)
The latter two are somewhat more efficient than looping over keys and running z[key] to obtain the value. It's also arguably more readable.
Building on these...
List Comprehensions
List comprehensions are great.
For the simple case of searching for just 'CI':
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> [key for key, value in z.items() if 'CI' in value]
['z']
For finding dict keys that hold several search items:
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> search_items = ('CI', 1) # Only keys that hold both CI and 1 will match
>>> [key for key, value in z.items() if all(item in value for item in search_items)]
['z']
For finding dict keys that hold any of multiple search items:
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> search_items = ('CI', 'SE', 'JP') # Keys that hold any of the three items will match
>>> [key for key, value in z.items() if any(item in value for item in search_items)]
['x', 'z']
If the latter two look a bit too complex as one-liners, you can re-write the last bit as a separate function.
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> search_items = ('CI', 'SE', 'JP') # Keys that hold any of the three items will match
>>> def match_any(dict_value, search_items):
... return any(item in dict_value for item in search_items)
...
>>> [key for key, value in z.items() if match_any(value, search_items)]
['x', 'z']
Once you get used to the [x for x in iterable if condition(x)] syntax, the format should be very easy to read and follow.
z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for i in z.keys(): #reaching the keys of dict
for x in z[i]: #reaching every element in tuples
if x=="CI": #if match found..
print ("{} holding {}.".format(i,x)) #printing it..
This might solve your problem.
Output:
>>>
q holding CI.
>>>
Edit for your comment:
def func(*args):
mylist=[]
z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for x,y in z.items():
for t in args:
if t in y:
mylist.append(x)
return mylist
print (func(1,"CI"))
Output:
>>>
['q', 'q', 'x']
>>>
Hope this is what you want, otherwise first method is already printing all keys, example output:
if x==1 or x=="CI":
>>>
x holding 1.
q holding CI.
q holding 1.
q holding 1.
>>>
There's no need to retrieve the key if you're only interested in the values:
In Python 2.x:
z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for value in z.itervalues():
if 'CI' in value:
return value
In Python 3.x:
z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for value in z.values():
if 'CI' in value:
return value
try this:
>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> list(filter(lambda x:'CI' in z.get(x),z))
['z']
z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for key, val in z.items():
if 'CI' in val:
return z[key]

Deleting from dict if found in new list in Python

Say I have a dictionary with whatever number of values.
And then I create a list.
If any of the values of the list are found in the dictionary, regardless of whether or not it is a key or an index how do I delete the full value?
E.g:
dictionary = {1:3,4:5}
list = [1]
...
dictionary = {4:5}
How do I do this without creating a new dictionary?
for key, value in list(dic.items()):
if key in lst or value in lst:
del dic[key]
No need to create a separate list or dictionary.
I interpreted "whether or not it is a key or an index" to mean "whether or not it is a key or a value [in the dictionary]"
it's a bit complicated because of your "values" requirement:
>>> dic = {1: 3, 4: 5}
>>> ls = set([1])
>>> dels = []
>>> for k, v in dic.items():
if k in ls or v in ls:
dels.append(k)
>>> for i in dels:
del dic[i]
>>> dic
{4: 5}
A one liner to do this would be :
[dictionary.pop(x) for x in list if x in dictionary.keys()]
dictionary = {1:3,4:5}
list = [1]
for key in list:
if key in dictionary:
del dictionary[key]
>>> dictionary = {1:3,4:5}
>>> list = [1]
>>> for x in list:
... if x in dictionary:
... del(dictionary[x])
...
>>> dictionary
{4: 5}
def remKeys(dictionary, list):
for i in list:
if i in dictionary.keys():
dictionary.pop(i)
return dictionary
I would do something like:
for i in list:
if dictionary.has_key(i):
del dictionary[i]
But I am sure there are better ways.
A few more testcases to define how I interpret your question:
#!/usr/bin/env python
def test(beforedic,afterdic,removelist):
d = beforedic
l = removelist
for i in l:
for (k,v) in list(d.items()):
if k == i or v == i:
del d[k]
assert d == afterdic,"d is "+str(d)
test({1:3,4:5},{4:5},[1])
test({1:3,4:5},{4:5},[3])
test({1:3,4:5},{1:3,4:5},[9])
test({1:3,4:5},{4:5},[1,3])
If the dictionary is small enough, it's easier to just make a new one. Removing all items whose key is in the set s from the dictionary d:
d = dict((k, v) for (k, v) in d.items() if not k in s)
Removing all items whose key or value is in the set s from the dictionary d:
d = dict((k, v) for (k, v) in d.items() if not k in s and not v in s)

How do I do this with Python list? (itemgetter?)

[{'id':44}, {'name':'alexa'},{'color':'blue'}]
I want to select whatever in the list that is "id".
Basically, I want to print 44, since that's "id" in the list.
That's a weird data structure... A list of one item dictionaries.
key = 'id'
l = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
print [ x[key] for x in l if key in x ][0]
Assuming you can rely on key being present precisely once...
Maybe you should just convert the list into a dictionary first:
key = 'id'
l = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
d = {}
for x in l:
d.update(x)
print d[key]
All the other answers solve your problem, I am just suggesting an alternative way of going about doing this.
Instead of having a list of dicts where you query on the key and have to iterate over all list items to get values, just use a dict of lists. Each key would map to a list of values (or just one value if all your dicts had distinct sets of keys).
So,
data=[{'id':44}, {'name':'alexa'},{'color':'blue'}]
becomes
data={'id':[44], 'name':['alexa'], 'color':['blue']}
and you can neatly access the value for 'id' using data['id'] (or data['id'][0] if you only need one value).
If all your keys are distinct across the dicts (as in your example) you don't even have to have lists of values.
data={'id':44, 'name':'alexa', 'color':'blue'}
Not only does this make your code cleaner, it also speeds up your queries which no longer have to iterate over a list.
Probably this is the best solution:
>>> L = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
>>> newd = {}
>>> for d in L:
... newd.update(d)
>>> newd['id']
44
You could do something like this:
>>> KEY = 'id'
>>>
>>> my_list = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
>>> my_ids = [x[KEY] for x in my_list if KEY in x]
>>> print my_ids
[44]
Which is obviously a list of the values you want. You can then print them as required.
>>> from itertools import dropwhile
>>> def find_value(l, key):
... return dropwhile(lambda x: key not in x, l).next()[key]
>>> find_value([{'id':44}, {'name':'alexa'},{'color':'blue'}], "id")
This will do a linear search, but only until the element is found.
If you want to have proper error handling, use:
def find_value(l, key):
try:
return dropwhile(lambda x: key not in x, l).next()[key]
except StopIteration:
raise ValueError(key)
>>> L = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
>>> newd=dict(d.items()[0] for d in L)
>>> newd['id']
44

Categories