Extracting a dictionary into a set of tuples - python

Giving this dictionary:
d = {'x': '999999999',
'y': ['888888888', '333333333'],
'z': '666666666',
'p': ['0000000', '11111111', '22222222'] }
is it possible to make a set of tuples ?
The output should be {( x, 999999999),(y,888888888, 333333333),...}
I tried this : x_set = {(k, v) for k, values in d.items() for v in values}

x_set = set()
for k, v in d.items():
items = [k]
if(type(v) == list):
items.extend(v)
else:
items.append(v)
x_set.add(tuple(items))
Check if the dictionary element is a list or not so you know whether to iterate through the element or simply append it.

You could construct a set of tuples with cases depending on whether the dictionary values are lists or not.
d = {'x': '999999999',
'y': ['888888888', '333333333'],
'z': '666666666',
'p': ['0000000', '11111111', '22222222'] }
tuple_set = set(tuple([k] + list(map(int, v)) if isinstance(v,list) else [k, int(v)]) for k,v in d.items())

Related

Extract a simple one from a nested dictionary and sort out elements based on a condition

The following dictionary is given:
dict_nested = {"A":{"C":100, "D":{"E":100, "F":100}}, "B":200}
The result should look like this:
dict_result = {"C":100, "E":100, "F":100, "B":200}
the result should be 1 Dictionary which only contain the key-value pairs, which its values are from type Integer and not dict.
the order should be maintained (i dont mean the alphabetical order of the keys)
Like Sembei said, recursion is needed for this case:
dict_nested = {"A":{"C":100, "D":{"E":100, "F":100}}, "B":200}
def extract_dict(d1, d2):
for k, v in d1.items():
if isinstance(v, dict):
extract_dict(v, d2)
elif isinstance(v, int):
d2.update({k: v})
dict_result = {}
extract_dict(dict_nested, dict_result)
print(dict_result)
Output:
{'C': 100, 'E': 100, 'F': 100, 'B': 200}

Remove dictionary entries based on length of key

Do dictionaries allow for filtering based on key length? Altering dictionaries conditionally based on value seems straightforward, but what about doing the same with keys? i.e. what would it take to delete all dictionary keys that are not explicitly 4 characters long?
You could use a dictionary comprehension:
d = {'fooo': 1, 'bar': 2, 'foo': 3}
result = {k: v for k, v in d.items() if len(k) == 4}
print(result)
Output
{'fooo': 1}
As krflol mentioned, if you don't want to build a whole new dictionary but
rather just modify your old dictionary, a straightforward for loop will do:
my_dict = {"a": 1, "abcd": 4, "": 9, "xyzt": 16}
for k in list(my_dict):
if len(k) != 4:
del my_dict[k]
print(my_dict)
Another way could be using filter, like so :
my_dict = dict(filter(lambda k: len(k) != 4, my_dict.items()))
This can be accomplished as seen in the following:
new_dict = {k: v for k, v in old_dict.items() if len(k) == 4}

compare values from a list with values from a dictionary

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}

Python3 dictionary comprehension with sub-dictionary upacking?

Suppose one has a dictionary, root which consists of key:value pairs, where some values are themselves dictionaries.
Can one (and if so, how) unpack these sub dictionaries via dictionary comprehension?
e.g.
{k: v if type(v) is not dict else **v for k, v in root.items()}
example:
root = {'a': 1, 'b': {'c': 2, 'd': 3}}
result = {'a': 1, 'c': 2, 'd': 3}
I guess I should post as an answer with a more broad explanation to help you as it is a little bit different to other existing questions
{
_k: _v
for k, v in root.items()
for _k, _v in ( # here I create a dummy dictionary if non exists
v if isinstance(v, dict) else {k: v}
).items() # and iterate that
}
The key part of understanding is that you need consistent and generic logic for the comprehension to work.
You can do this by creating dummy nested dictionaries where they don't previously exist using v if isinstance(v, dict) else {k: v}
Then this is a simple nested dictionary unpacking exercise.
To help in your future comprehensions I would recommend writing the code out e.g.
res = dict()
for k,v in root.items():
d = v if isinstance(v, dict) else {k: v}
for _k, _v in d.items():
res[_k] = _v
and work backwards from this
Useful references
Putting a simple if-then-else statement on one line
Nested dictionary comprehension python
If you have several levels of nested dictionaries, I suggest you the following solution based on a recursive function:
def flatten(res, root):
for k,v in root.items():
if isinstance(v, dict):
flatten(res, v)
else:
res[k] = v
root = {'a': 1, 'b': {'c': 2, 'd': {'e': 5, 'f': 6}}}
result = {}
flatten(result, root)
print(result) # {'a': 1, 'c': 2, 'e': 5, 'f': 6}
Here is a recursive solution. In the function _flatten_into_kv_pairs, we iterate through the key and values pair and yield those keys/values if the value is a not a dictionary. If it is, then we recursively call _flatten_into_kv_pairs with the yield from construct. The function flatten_dict is just a shell which turns sequence of key/value pairs back into a dictionary.
def _flatten_into_kv_pairs(dict_object):
for k, v in dict_object.items():
if isinstance(v, dict):
yield from _flatten_into_kv_pairs(v)
else:
yield k, v
def flatten_dict(dict_object):
return dict(_flatten_into_kv_pairs(dict_object))
root = {'a': 1, 'b': {'c': 2, 'd': 3, 'e': {'f': 4, 'g': 5}}}
print(flatten_dict(root))
Output:
{'a': 1, 'c': 2, 'd': 3, 'f': 4, 'g': 5}

Average from two list of dictionaries

I have two list of dictionaries and I want to find the average of values from each of them based upon the key value. i.e I want to match the keys and average its values from list of dictionaries.
data = {'5649a533c95a8a0bc345d1fe': [{'1': 0.0}, {'2': 28652.343535112403}, {'3': 26505.012833437846}],
'5649a533c95a8a0bc345d20c': [{'1': 28652.343535112403}, {'2': 26505.012833437846}, {'3': 24518.570421292356}]}
I want to match the keys i.e '1' in both the list of dictionaries and then do the average of its respective values.
E.g In the above dataset, I need to get the values 0.0 and 28652.343535112403 matched by the keys i.e '1' and then do the average of the values.
The expected result is [{'1': 20000}, {'2': 230000}, {'3': 23000}]
I am able to iterate the dictionary but I am lost after that.
This is what I have tried to do
for k, v in data.items():
for index, i in enumerate(v, start=1):
print(index, i[str(index)])
Please help.
Try:
d = {}
for x in itertools.chain(data.values()):
for k,v in x.items():
if k in d:
d[k].append(v)
else:
d[k] = [v]
av = {}
for k,v in d.items():
av[k]=sum(v)/len(v)
print av
I got a results:
{'1': 14326.171767556201, '3': 25511.7916273651, '2': 27578.678184275122}
Note: Based on your values on data, you cant have the average:
[{'1': 20000}, {'2': 230000}, {'3': 23000}]
Another try may be-
d = []
for k, v in data.items():
dd = []
for index, i in enumerate(v, start=1):
dd.append((index, i[str(index)]))
d.append(dd)
av_1 = []
av_2 = []
for (x,y) in zip(d[0],d[1]):
l1 = (x[0],y[0])
l2= (x[01],y[1])
l1_av = reduce(lambda x, y: x + y, l1) / len(l1)
l2_av = reduce(lambda x, y: x + y, l2) / len(l2)
av_1.append(l1_av)
av_2.append(l2_av)
print {k:v for k,v in zip(av_1,av_2)}
Output
{1: 14326.171767556201, 2: 27578.678184275122, 3: 25511.7916273651}

Categories

Resources