Indexing Dict with Multiple values at one key - python

I'm new to python and I was wondering if there's a way for me to pull a value at a specific index. Let's say I have a key with multiple values(list) associated with it.
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
Let's say I want to iterate through values and print out the value if it's equal to 'DOG'. Do Values, Key pairs have a specific index associated with the position of Values?
I've try reading up on dict and how it works apparently you can't really index it. I just wanted to know if there's a way to get around that.

You can perform the following (comments included):
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
for keys, values in d.items(): #Will allow you to reference the key and value pair
for item in values: #Will iterate through the list containing the animals
if item == "DOG":
print(item)
print(values.index(item)) #will tell you the index of "DOG" in the list.

So maybe this will help:
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
for item in d:
for animal in (d[item]):
if animal == "DOG":
print(animal)
Update -What if I want to compare the string to see if they're equal or not... let say if the value at the first index is equal to the value at the second index.
You can use this:
d = {'ANIMAL' : ['CAT','DOG','FISH','HEDGEHOG']}
for item in d:
for animal in (d[item]):
if animal == "DOG":
if list(d.keys())[0] == list(d.keys())[1]:
print("Equal")
else: print("Unequal")

Keys and values in a dictionary are indexed by key and do not have a fixed index like in lists.
However, you can leverage the use of 'OrderedDict' to give an indexing scheme to your dictionaries. It is seldom used, but handy.
That being said, dictionaries in python3.6 are insertion ordered :
More on that here :
Are dictionaries ordered in Python 3.6+?

d = {'animal': ['cat', 'dog', 'kangaroo', 'monkey'], 'flower': ['hibiscus', 'sunflower', 'rose']}
for key, value in d.items():
for element in value:
if element is 'dog':
print(value)
does this help? or, you want to print index of key in dictionary?

Related

How to index a list of dictionaries in python?

If I have a list of dictionaries in a python script, that I intend to later on dump in a JSON file as an array of objects, how can I index the keys of a specific dictionary within the list?
Example :
dict_list = [{"first_dict": "some_value"}, {"second_dict":"some_value"}, {"third_dict": "[element1,element2,element3]"}]
My intuitive solution was dict_list[-1][0] (to access the first key of the last dictionary in the list for example). This however gave me the following error:
IndexError: list index out of range
the key inputted into the dictionary will pick the some value in the format dict = {0:some_value}
to find a specific value:
list_dictionary = [{"dict1":'value1'},{"dict2","value2"}]
value1 = list_dictionary[0]["dict1"]
the 'key' is what you have to use to find a value from a dictionary
Example:
dictionary = {0:value}
dictionary[0]
in this case it will work
but to pick the elements we will do
values = []
for dictionary in dict_list:
for element in dictionary:
values.append(dictionary[element])
Output:
['some_value', 'some_value', ['element1', 'element2', 'element3']]
dict_list = [{"first_dict": "some_value"}, {"second_dict":"some_value"}, {"third_dict": ['element1','element2','element3']}]
If your dict look like this you can do as well
dict_list[-1]["third_dict"]
You can't access 'the first key' with a int since you have a dict
You can get the first key with .keys() and then
dict_list[-1].keys()[0]
By using dict_list[-1][0], you are trying to access a list with a list, which you do not have. You have a list with a dict key within a list.
Taking your example dict_list[-1][0]:
When you mention dict_list you are already "in the list".
The first index [-1] is referring to the last item of the list.
The second index would only be "usable" if the item mentioned in the previous index were a list. Hence the error.
Using:
dict_list=[{"first_dict": "some_value"}, {"second_dict":"some_value"},{"third_dict": [0,1,2]}]
to access the value of third_dict you need:
for value in list(dict_list[-1].values())[0]:
print(value)
Output:
0
1
2
If you know the order of dictionary keys and you are using one of the latest python versions (key stays in same order), so:
dict_list = [
{"first_dict": "some_value"}
, {"second_dict":"some_value"}
, {"third_dict": ["element1", "element2", "element3"]}
]
first_key = next(iter(dict_list[-1].keys()))
### OR: value
first_value = next(iter(dict_list[-1].values()))
### OR: both key and value
first_key, first_value = next(iter(dict_list[-1].items()))
print(first_key)
print(first_key, first_value)
print(first_value)
If you have the following list of dictionaries:
dict_list = [{"key1":"val1", "key2":"val2"}, {"key10":"val10"}]
Then to access the last dictionary you'd indeed use dict_list[-1] but this returns a dictionary with is indexed using its keys and not numbers: dict_list[0]["key1"]
To only use numbers, you'd need to get a list of the keys first: list(dict_list[-1]). The first element of this list list(dict_list[-1])[0] would then be the first key "key10"
You can then use indices to access the first key of the last dictionary:
dict_index = -1
key_index = 0
d = dict_list[dict_index]
keys = list(d)
val = d[keys[key_index]]
However you'd be using the dictionary as a list, so maybe a list of lists would be better suited than a list of dictionaries.

How do I merge dictionaries having similar values in Python?

I have a problem.
Input=[
{'id':uuid1(),'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'id':uuid1(),'name':'cpu','point':[{'second':10,'severity':'warning'}],'date':'2021-09-13','PO':3},
{'id':uuid1(),'name':'cpu','point':[{'second':20,'severity':'critical'}],'date':'2021-09-14','PO':3},
{'id':uuid1(),'name':'cpu','point':[{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}]
I will compare in this array. If the same name, I will combine all value of this dict.
It mean combine all value of key 'point'. I will have key list 'point' with multi dict
We have many duplicate key name = 'cpu'. So I will combine all value if the same value.U see we have PO the same value (PO=3 with name=cpu).If different value, we will take the last value(last value 'date':'2021-09-15').Finally, we will append the dicts in the key point list together
Desired result
Output=[
{'id':uuid1(),'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'id':uuid1(),'name':'cpu','point':[{'second':10,'severity':'warning'},
{'second':20,'severity':'critical'},
{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}
]
Note: I use python 3.6
I hope someone will help me. Thank you very muck
There is probably a better way to do this but the following works:
a=[{'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'name':'cpu','point':[{'second':10,'severity':'warning'}],'date':'2021-09-13','PO':3},
{'name':'cpu','point':[{'second':20,'severity':'critical'}],'date':'2021-09-14','PO':3},
{'name':'cpu','point':[{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}]
b=[]
for i in a:
for j in b:
if i['name'] == j['name']:
j['point'] += i['point']
break
else:
b.append(i)

Python dictionary check if the values match with other key values

I have created a python dictionary with a structure like :-
mydict = {'2018-08' : [32124,4234,23,2323,32423,342342],
'2018-07' : [13123,23424,2,3,4343,4232,2342],
'2018-06' : [1231,12,12313,12331,3123131313,434546,232]}
I want to check if any value in the values of key '2018-08' match with any values of other keys. is there a short way to write this?
You can simply loop over your expected values of mydict, and then for each of them check if its present in any of the values of the dictionary
You can use the idiom if item in list to check if item item is present in the list list
expected_values = mydict['2018-08']
found = False
for expected in expected_values:
for key in mydict:
if expected in mydict[key]:
found = True
break
Take into account that is a brute force algorithm and it may not be the optimal solution for larger dictionaries
The question is vague, so I am assuming that you want the values in the target month (e.g. 2018-08) that are contained somewhere within the other months.
Sets are much faster for testing membership compared to list iteration.
target = '2018-08'
s = set()
for k, v in mydict.iteritems():
if k != target:
s.update(v)
matches = set(mydict[target]) & s
Can use itertools.chain to create a long list
import itertools
for key,value in mydict.items():
temp_dict = mydict.copy()
temp_dict.pop(key)
big_value_list=list(itertools.chain(*temp_dict.values()))
print(key, set(value) & set(big_value_list))
Dry run by changing your provided inputs
mydict = {'2018-08' : [32124,4234,23,2323,32423,342342],
'2018-07' : [13123,23424,2,3,4343,4232,2342],
'2018-06' : [1231,12,12313,12331,3123131313,434546,232,342342,2342]}
Output:
('2018-08', set([342342]))
('2018-07', set([2342]))
('2018-06', set([342342, 2342]))

Checking items in a list of dictionaries in python

I have a list of dictionaries=
a = [{"ID":1, "VALUE":2},{"ID":2, "VALUE":2},{"ID":3, "VALUE":4},...]
"ID" is a unique identifier for each dictionary. Considering the list is huge, what is the fastest way of checking if a dictionary with a certain "ID" is in the list, and if not append to it? And then update its "VALUE" ("VALUE" will be updated if the dict is already in list, otherwise a certain value will be written)
You'd not use a list. Use a dictionary instead, mapping ids to nested dictionaries:
a = {
1: {'VALUE': 2, 'foo': 'bar'},
42: {'VALUE': 45, 'spam': 'eggs'},
}
Note that you don't need to include the ID key in the nested dictionary; doing so would be redundant.
Now you can simply look up if a key exists:
if someid in a:
a[someid]['VALUE'] = newvalue
I did make the assumption that your ID keys are not necessarily sequential numbers. I also made the assumption you need to store other information besides VALUE; otherwise just a flat dictionary mapping ID to VALUE values would suffice.
A dictionary lets you look up values by key in O(1) time (constant time independent of the size of the dictionary). Lists let you look up elements in constant time too, but only if you know the index.
If you don't and have to scan through the list, you have a O(N) operation, where N is the number of elements. You need to look at each and every dictionary in your list to see if it matches ID, and if ID is not present, that means you have to search from start to finish. A dictionary will still tell you in O(1) time that the key is not there.
If you can, convert to a dictionary as the other answers suggest, but in case you you have reason* to not change the data structure storing your items, here's what you can do:
items = [{"ID":1, "VALUE":2}, {"ID":2, "VALUE":2}, {"ID":3, "VALUE":4}]
def set_value_by_id(id, value):
# Try to find the item, if it exists
for item in items:
if item["ID"] == id:
break
# Make and append the item if it doesn't exist
else: # Here, `else` means "if the loop terminated not via break"
item = {"ID": id}
items.append(id)
# In either case, set the value
item["VALUE"] = value
* Some valid reasons I can think of include preserving the order of items and allowing duplicate items with the same id. For ways to make dictionaries work with those requirements, you might want to take a look at OrderedDict and this answer about duplicate keys.
Convert your list into a dict and then checking for values is much more efficient.
d = dict((item['ID'], item['VALUE']) for item in a)
for new_key, new_value in new_items:
if new_key not in d:
d[new_key] = new_value
Also need to update on key found:
d = dict((item['ID'], item['VALUE']) for item in a)
for new_key, new_value in new_items:
d.setdefault(new_key, 0)
d[new_key] = new_value
Answering the question you asked, without changing the datastructure around, there's no real faster way of looking without a loop and checking every element and doing a dictionary lookup for each one - but you can push the loop down to the Python runtime instead of using Python's for loop.
I haven't tried if it ends up faster though.
a = [{"ID":1, "VALUE":2},{"ID":2, "VALUE":2},{"ID":3, "VALUE":4}]
id = 2
tmp = filter(lambda d: d['ID']==id, a)
# the filter will either return an empty list, or a list of one item.
if not tmp:
tmp = {"ID":id, "VALUE":"default"}
a.append(tmp)
else:
tmp = tmp[0]
# tmp is bound to the found/new dictionary

how to pop right most(lowest value) item from dictionary?

So let's say I have the following dictionary:
dic = {'a':3, 'b':2, 'c':1, 'd':1}
So I want to pop (or any other method, that remove and return) 'd' because it is the lowest
Value and the right most item (in case 2 keys have the same value), values will always be ints.
I tried:
dic.popItem()
But I'm just getting a random item back, any ideas?
Also tried:
temp = min(dic.values)
del dic[temp]
But again, it's not working!
There's no such thing as the right-most item, because dictionaries are unordered.
You can delete one of the lowest-value items like this:
item = min(dic, key=dic.get)
del dic[item]
You need an ordereddict to get a consistent result.
See this post:
Sort a Python dictionary by value

Categories