I have a dict like this:
d = {'first':'', 'second':'', 'third':'value', 'fourth':''}
and I want to find first non-empty value (and it's name, in this example 'third'). There may be more than one non-empty value, but I only want the first one I find.
How can I do this?
Use an OrderedDict which preserves the order of elements. Then loop over them and find the first that isn't empty:
from collections import OrderedDict
d = OrderedDict()
# fill d
for key, value in d.items():
if value:
print(key, " is not empty!")
You could use next (dictionaries are unordered - this somewhat changed in Python 3.6 but that's only an implementation detail currently) to get one "not-empty" key-value pair:
>>> next((k, v) for k, v in d.items() if v)
('third', 'value')
Like this?
def none_empty_finder(dict):
for e in dict:
if dict[e] != '':
return [e,dict[e]]
d = {'first':'', 'second':'', 'third':'value', 'fourth':''}
for k, v in d.items():
if v!='':
return k, v
Edit 1
from the comment if the value is None or '' we better use if v: instead of if v!=''. if v!='' only check the '' and skip others
You can find empty elements and make a list of them:
non_empty_list = [(k,v) for k,v in a.items() if v]
By using list comprehension, you can list all the non-empty values and then fetch the 0th value:
[val for key, val in d.items() if val][0]
Related
I am attempting to remove key-value pairs from a dict when a sub-dictionary matches values from another dictionary.
Example set-up:
e = {'a':{'aa':'yes'}, 'b':{'ac':'no'}, 'a':{'aa':'yes'}}
f = {'a':{'aa':'yes'}, 'e':{'ab':'no'}, 'a':{'aa':'yes'}}
for keys, values in e.items():
for k, v in f.items():
if values.get('aa') == v.get('aa'):
e.pop(keys)
RuntimeError: dictionary changed size during iteration
Expected result:
#from
e = {'a':{'aa':'yes'}, 'b':{'ac':'no'}, 'a':{'aa':'yes'}}
#to
e = {'b':{'ac':'no'}}
With single dict comprehension:
e = {k:v for k, v in e.items() if v.items() != f.get(k, {}).items()}
{'b': {'ac': 'no'}}
dict.get(key[, default]) allows you to set the needed(or preferred) default value returned for the key in dict
In general, you should not add or remove items from iterables that you are currently iterating over.
As you've been told, you can't modify the length of a thing while you're iterating it. There are a few options here, such as:
Saving a list of what you want to remove, then doing it later:
to_remove = []
for keys, values in e.items():
for k, v in f.items():
if values.get('aa') == v.get('aa'):
to_remove.append(keys)
for tr in to_remove:
e.pop(tr)
Cloning the object, so that what you're iterating does not change but the original object can be modified. This is even more memory expensive than the previous however.
for keys, values in dict(e).items(): # or list(e.items())
for k, v in f.items():
if values.get('aa') == v.get('aa'):
e.pop(keys)
You could also, in your case, simply create a new object:
g = {}
for keys, values in e.items():
for k, v in f.items():
if values.get('aa') != v.get('aa'):
g[keys] = values
Is it possible to create a list comprehension for the below for loop?
for key, value in some_dict.items():
if my_value in value:
my_new_var = value['sub_item'].split[0]
This will work :
d={'name':'Yash','age':16}
###############################
keys_values = d.items() # Bonus: Converting the dictionary keys and values to string
d = {str(key): str(value) for key, value in keys_values}#--- ''
#########################
my_value='Yash'
my_new_var = [v for k, v in d.items() if my_value in v] [-1] # edit: now it'll take last value
print(my_new_var)
i managed to do something like this:
out = [value['sub_value'].split[0] for key, value in some_dict.items() for i in value if my_new_var in value]
So what I was trying to do was output the string "33k22k11k", which is just the last value followed by the reversed last key followed by the second last value followed by the second last reversed key and so on. I'm not sure how to get the reversed key value for the specific loop that I am in. From the code I currently I have, I get the output:
dict = {"k1":1, "k2":2, "k3":3}
current=""
current_k=""
for k,v in dict.items():
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
33k2k1k22k1k11k
3k2k1k
Edited
First of all, if you are on python < 3.6, dict does not keep the order of items. You might want to use collections.OrderedDict for your purpose.
d = {"k1":1, "k2":2, "k3":3}
d.keys()
# dict_keys(['k2', 'k1', 'k3'])
whereas,
d = OrderedDict()
d['k1'] = 1
d['k2'] = 2
d['k3'] = 3
d.keys()
# odict_keys(['k1', 'k2', 'k3'])
With our new d, you can either add the key and values and reverse it:
res = ''
for k, v in d.items():
res += str(k) + str(v)
res[::-1]
# '33k22k11k'
or reversely iterate:
res = ''
for k, v in reversed(d.items()):
res += str(v)[::-1] + str(k)[::-1]
res
# '33k22k11k'
I may be wrong but it seems like you would want to reset the value of current_k each time you access a new key
dict = {"k1":1, "k2":2, "k3":3}
current=""
for k,v in dict.items():
current_k=""
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
Why not simply do:
print(''.join([a+str(b) for a,b in dict.items()])[::-1])
Output:
"33k22k11k"
But if the values are different from the keys, do:
print(''.join([str(b)[::-1]+a for a,b in dict.items()[::-1]]))
You can use the Python map function to create the reversed string(using f-string) for each key/value pair and then join it.
dict1 = {"k1":1, "k2":2, "k3":3}
new_dict = "".join(map(lambda k, v: f'{k}{v}'[::-1] , dict1.keys(), dict1.values()))
Output:
33k22k11k
You can do something like this perhaps:
dict = {"k1":1, "k2":2, "k3":3}
print("".join(list(reversed([str(v)+"".join(reversed(k)) for k, v in dict.items()]))))
Output:
33k22k11k
I have a dict as below
{"low":[18,12,9],"medium":[6,3],"high":[2,1],"final":[0]}
and I want to search for a number in this dict and get its respective 'key'
Eg: for 12, i need to return 'low'. slly for 2, return 'high'
You can use a dictionary comprehension for this.
dict = {"low":[18,12,9],"medium":[6,3],"high":[2,1],"final":[0]}
key = {k:v for k, v in dict.items() if 12 in v}
Output
In[1]: key.popitem()[0]
Out[1] : 12
This is a job for next.
my_d = {"low":[18,12,9],"medium":[6,3],"high":[2,1],"final":[0]}
target = 12
res = next((k for k, v in my_d.items() if target in v), 'N\A')
print(res) # low
Note that if your target value exists in more than one keys, this code will return one of them at random1. If that might by the case and depending on the problem you are working on it may be wiser to get all matching keys instead. To do that, use:
res = [k for k, v in my_d.items() if target in v]
1Actually more like in an uncontrolled fashion.
def getKey(number):
for key, value in d.iteritems():
if number in value:
return key
dict = {"low":[18,12,9],"medium":[6,3],"high":[2,1],"final":[0]}
def search_key(val):
for key, value in dict.iteritems():
for i in value:
if i == val:
print "the key is:"+key
return key
#pass any value for which you want to get the key
search_key(9)
So, I've been searching endlessly for something similiar to Lua's "Generic For Loop" in Python.
I've been working on a simple text based game in Python, and I've been working with dictionaries a lot.
Here is something I'm looking for (in Lua):
Dictionary = {
"Red" = "There is some red paint on the walls.",
"Green" = "There is a little bit of green paint on the floor.",
}
for i, v in pairs(Dictionary) do
print(i, v)
end
What this will do is, go through the dictionary, then print out the INDEX and the VALUE. How would I do something like this in Python?
I know there is this:
for i in Dictionary:
print(i)
But that just prints the INDEX. I would like to access both the INDEX and the VALUE. Something like:
for i, v in Dictionary:
print(i, v)
Any help is appreciated.
You're looking for items. Iterating over a dict just gives you the keys, so you'd have to do:
for key in my_dict:
x = my_dict[key]
What you want is this:
for key, value in my_dict.items():
# do something
two ways:
for i, v in Dictionary.items():
print(i, v) #outputs pairs as key value
for tup in Dictionary.items(): #same thing
print(tup) # outputs pairs as (key,value)
or
for key in Dictionary:
print(key,Dictionary[key])
EDIT RESPONSE TO COMMENT:
>>> d = {1:1,2:2,3:3,4:4}
>>> for item in d.items(): print(item)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
>>> for key,val in d.items(): print(key,val)
1 1
2 2
3 3
4 4
this is because in the first loop, item is a tuple and the __repr__ for a tuple has the brackets and commas as part of it where as the second loop splits the tuple into two seperate variables. print then automatically adds a space delimiter in between each parameter passed in the print function.
As explained by Two-Bit Alchemist:
In case it's not entirely clear still, in the tup formulation you'd access the key and value as tup[0] and tup[1], respectively. for key, val in my_dict.items(): ... and for tup in my_dict.items(): key, val = tup is the same setup. The point is you can use tuple unpacking just fine inline in a for loop.
The items method (or in Py2, viewitems or iteritems to avoid making a whole new list containing copies of the dict key/value pairs) is the way to go:
for k, v in Dictionary.items(): # For performance, use .viewitems() on Py2.7, .items() on Py3.x
print(k, v)