How to get the innermost value among dictionaries at one go? - python-3.x

Here is my dictionary:
my_dict = {'00.Life': help}
help ={'A.Death':['dying','dead','mourir','pass away']}
I have one dictionary inside the other one.
How to get the innermost value at one go?
I hope I could just input 'dying'(one of the elements in the list) to get ['dying','dead','mourir','pass away'] list.
How to do that?

You can't do it "at one go" using your existing data structure. You will have to either iterate all the values, or construct a reversed, lookup dictionary first. For example:
>>> my_help ={'A.Death':['dying','dead','mourir','pass away']}
>>> my_dict = {'00.Life': my_help}
>>> lookup_dict = {k: v for v in my_dict["00.Life"].values() for k in v}
>>> lookup_dict["dying"]
['dying', 'dead', 'mourir', 'pass away']

Related

Iterate through dictionary by indexes

How to bypass python out of box mechanism when an order of items() in the loop does not correspond to the order it supposes to be?
st = 'Tree'
freq = Counter(st)
sorted(freq.items(), key=lambda item: item[1])
arr = []
for k, v in freq.items():
for i in range(v):
arr.append(k)
I expect to get in the first iteration pair: ('e', 2), but instead it is ('t', 1).
But sorting was applied to dictionary at row 3.
How to iterate dictionary in way it is sorted? (without applying underhood re-order)
UPD. The question has already been answered, however, will be good to know why dictionaries implemented in Python3 in that way.
sort by keys:
a = dict(b=3, c=5, a=10)
for k in sorted(a):
print(f"{k}: {a[k]}")
and if you want to sort them by the values:
a = dict(b=3, c=5, a=10)
for k, v in sorted(a.items(), key=lambda item: item[1]):
print(f"{k}: {a[k]}")

Convert elements in ONE list to keys and values in a dictionary

I'm looking for a way to convert a list to a dictionary as shown below. Is this possible? Thanks in advance.
list = ["1/a", "2/b", "3/c"]
dict = {"1": "a", "2": "b", "3": "c"}
Of course it is possible.
First, you can split an element of the list with e.split("/"), which will give a list for example splitted = ["1", "a"].
You can assign the first element to the key and the second to the value:
k = splitted[0]
v = splitted[1]
or another way to express that:
k,v = splitted
Then you can iterate over your list to build your dict, so if we wrap this up (you should not call a list list because list is a type and an already existing identifier:
d = {}
for e in elements:
k,v = e.split("/")
d[k] = v
You can also do that in one line with a dict comprehension:
d = {k:v for k,v in [e.split("/") for e in elements]}
Yes you can.
If you want to have everything after the '/' (i.e. 2nd char), you can do:
dict = {c[0]:c[2:] for c in list}
If you want to have everything after the '/' (but may not be the 2nd char), you can do:
dict = {c[0]:c.split('/')[1] for c in list}
It really dependes on the input you have and what output you want
You can do like this.
lista = ["1/a", "2/b", "3/c"]
new_dict = {}
for val in lista:
new_dict.update({val[0]:val[2]})
print(new_dict)
Try this
list = ["1as/aasc", "2sa/bef", "3edc/cadeef"]
dict = {i.split('/')[0]:i.split('/')[1] for i in list}
Answer will be
{'1as': 'aasc', '2sa': 'bef', '3edc': 'cadeef'}
I have given a different test case. Hope this will answer your question.

Matching character lists of unequal length

I want to match two lists from which one list is smaller while other is a bigger one. If a match occurs between two lists then put the matching element in a new list at the same index instead of putting it another index. You can understand my question from the code given below:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist = []
smaller_list_len = min(len(list1),len(list2))
for ind in range(smaller_list_len):
elem2 = list1[ind]
elem1 = list2[ind][0:2]
if elem1 in list2:
matchlist.append(list1[ind])
Obtained output
>>> matchlist
['KNJ', 'NJK', 'JNJ']
Desired Output
>>> matchlist
['AFG', 'KNJ', 'JNJ', 'NJK']
Is there a way to get the desired output?
Use a nested loop iterating over the 3-char list. When an item in that list contains the current item in the 2-char list, append it and break out of the inner loop:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist = []
smaller_list_len = min(len(list1),len(list2))
for ind in range(smaller_list_len):
for item in list2:
if list1[ind] in item:
matchlist.append(item)
break
Given the question doesn't specify any constraints, in a more pythonic way, using a list comprehension:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist=[e2 for e1 in list1 for e2 in list2 if e2.startswith(e1)]
produces
['AFG', 'KNJ', 'JNJ', 'NJK']

how to convert dict_values into a set

I have a dict that contains sets as values for each key, e.g.
{'key1': {8772, 9605},'key2': {10867, 10911, 10917},'key3': {11749,11750},'key4': {14721, 19755, 21281}}
Now I want to put each value, i.e. set of ints into a set, I am wondering what is the best way/most efficient way to do this.
{8772,9605,10867,10911,10917,11749,11750,14721,19755,21281}
I tried to retrieve the values from the dict using dict.values(), but that returns a dict_values object, making it a list, list(dict.values()) gave me a list of sets, set(list(exact_dups.values())) threw me errors,
TypeError: unhashable type: 'set'
UPDATE. forgot to mention the result set also need to maintain uniqueness, i.e. no duplicates.
You can do it with set.union() and unpacked values:
set.union(*my_dict.values())
Or you can combine set.union() with reduce:
reduce(set.union, my_dict.values())
Use a combination of reduce and set union:
from functools import reduce
result = reduce(lambda a, b: a.union(b), my_dict.values(), set())
print(result)
A sequence reduction with the set union operator (|, "or") will do:
from functools import reduce
from operator import or_
d = {'key1': {8772, 9605},'key2': {10867, 10911, 10917},'key3': {11749,11750},'key4': {14721, 19755, 21281}}
s = reduce(or_, d.values())
It essentially does d['key1'] | d['key2'] | ....
Very simple, readable, self-explanatory solution without any imports:
arr = []
for key in dictionary:
arr += list(dictionary[key])
answer = set(arr.sorted())
A simpler way
set1 = set()
for i in dict.values():
set1.update(i)
set1
You can try this way:
keys_set= set()
for item in dict.values():
keys_set.add(item)
We can access only values as that's what OP wants and then sort it as follows :
dict1 = {'key1': {8772, 9605},'key2': {10867, 10911, 10917},'key3': {11749,11750},'key4': {14721, 19755, 21281}}
arr = []
for key in sorted(dict1.values()):
arr += key
print('{', ','.join(str(n) for n in arr), '}', sep='')
produces,
{8772,9605,10867,10917,10911,11749,11750,14721,19755,21281}
[Program finished]
as requested by OP.

Is it possible to delete keys meeting some criterion using a simple iteration in Python3?

Suppose we have a dict d={"key1":-1,"key2":-2,"key3":3,"key4":0,"key5":-7,"key6":1,...} in python3. Now I want to delete keys whose value is negative, e.g.,"key1":-1,"key2":-2,etc. I tried to write a code like this:
for k in d:
if d[k]<0:
del d[k]
But I received error saying "RuntimeError: dictionary changed size during iteration". From this message, it seems that it is not possible to delete keys of a dictionary meeting some criterion using a simple iteration, so at the moment, I have to save the keys to be deleted in a list, then write another iteration to remove them from d. My question is: is it really impossible to remove some of keys using a single iteration? If it's possible, could you please give a sample code of Python3 that can remove keys meeting some criterion using a simple iteration in Python3? Thank you.
Method #1: use a dictionary comprehension. This doesn't delete so much as replace, but gets you to the same d.
>>> d = {"key1":-1,"key2":-2,"key3":3,"key4":0,"key5":-7}
>>> d = {k: v for k,v in d.items() if v >= 0}
>>> d
{'key3': 3, 'key4': 0}
Method #2: iterate over an independent copy of the keys:
>>> d = {"key1":-1,"key2":-2,"key3":3,"key4":0,"key5":-7}
>>> for k in set(d):
... if d[k] < 0:
... del d[k]
...
>>> d
{'key3': 3, 'key4': 0}
Iterate over the keys instead of the dict:
for k in d.keys():
if d[k]<0:
del d[k]
For this to work in Python 3.X, keys() returns an iterator, so you need to use the following first line:
for k in list(d.keys()):

Resources