I am trying to write a function that:
Counts the number of "sub-keys" of a key (e.g. 'e' is a sub-key of 'M')
Divides each sub-key's probability by the total number of sub-keys for that key
Modifies the numbers in place.
My function has to return None, however.
For example, if I had the dictionary:
defaultdict(dict, {'M': {'e': 1.0}, 'O': {'n': 2, 'x': 1.0}, 'I': {'_': 1.0, 's': 1}, 'P': {'t': 3}, 'L': {'ne': 1, 'n': 1.0}})
So for the example dictionary the converted dictionary output would be:
defaultdict(<class 'dict'>, {'M': {'e': 1.0}, 'O': {'n': 0.6666666666666666, 'x': 0.3333333333333333}, 'I': {'_': 0.5, 's': 0.5}, 'P': {'t': 1.0}, 'L': {'ne': 0.5, 'n': 0.5}})
Another example, if I had the dictionary:
defaultdict(dict, {('H', 't'): {'m': 2}, ('M', 'o'): {'ce': 1, 'p': 2}, ('K', '^'): {'d': 2}, ('F', 'x'): {'_': 1, 'g': 3}, ('J', 'o'): {'y': 1}, ('A', 'b'): {'k': 3}, ('X', '_'): {'r': 1}, ('N', 'e'): {'x': 1}})
The converted dictionary would be:
defaultdict(<class 'dict'>, {('M', 'o'): {'ce': 0.3333333333333333, 'p': 0.6666666666666666}, ('K', '^'): {'d': 1.0}, ('F', 'x'): {'g': 0.75, '_': 0.25}, ('J', 'o'): {'y': 1.0}, ('H', 't'): {'m': 1.0}, ('A', 'b'): {'k': 1.0}, ('X', '_'): {'r': 1.0}, ('N', 'e'): {'l': 1.0}})
How would I go about doing this? How do I access keys within a defaultdict of dictionaries. What I am currently thinking is:
for major_key in dictionary:
dictionary[major_key]...
...and that's where I get stuck.
Any help would be greatly appreciated!
Aside from being able to iterate over just the keys in dictionaries, in Python you can also iterate over key-value tuples , or just values. So we could do something like this:
for major_key, sub_dict in d.items():
total_key_count = 0
# Add up all sub key values to calculate probabilities
for sub_count in sub_dict.values():
total_key_count += sub_count
# Now update nested dictionary values accordingly
for minor_key, sub_count in sub_dict.items():
sub_dict[minor_key] = sub_count / total_key_count
That should help give you the results you want. Note in Python 2 you should call iteritems() instead of items(), since in Python 2 items() actually builds a list of tupes, rather than returning an iterator like iteritems() does. Same with values() and itervalues().
Related
I am new to Python, so I may have the name of this wrong. The issue I am having is, I have a list as follow
lst1 = [{'A': ['99']}, {'B': ['83']}, {'D': ['65']}, {'J': ['90']}, {'A': ['99']}, {'B': ['85']}, {'D': ['63']}, {'J': ['89']}, {'A': ['95']}, {'B': ['79']}, {'D': ['63']}, {'J': ['73']}, {'A': ['98']}, {'B': ['82']}, {'D': ['81']}, {'J': ['91']}]
I am trying to see if there is a way to combine the the element within the [] that have the same key, so the resulting list will be
new_lst = [{'A': [99, 99, 95, 98]}, {'B': [83, 85, 79, 82]}, {'D': [65, 63, 63, 81]}, {'J': [90, 89, 73, 91]}]
I have been banging my head against the monitor for a few days now and I cannot figure it out, I would definitely appreciate any help.
Thank you,
If the output format has to be a list of dictionaries like the input, this is very complicated. It gets easy if you use a dictionary directly for the output. You then can use dict.setdefault(...):
inputlist = [
{'A': ['99']},
{'B': ['83']},
{'D': ['65']},
{'J': ['90']},
{'A': ['99']},
{'B': ['85']},
{'D': ['63']},
{'J': ['89']},
{'A': ['95']},
{'B': ['79']},
{'D': ['63']},
{'J': ['73']},
{'A': ['98']},
{'B': ['82']},
{'D': ['81']},
{'J': ['91']}
]
output = dict()
for dct in inputlist:
key = list(dct.keys())[0] # get the letter (A, B, D, J)
output.setdefault(key, []) # create the key in the output dictionary and assign a list to it, if it doesn't exist already
output[key] += dct[key] # append the number
print(output)
Output:
{'A': ['99', '99', '95', '98'], 'B': ['83', '85', '79', '82'], 'D': ['65', '63', '63', '81'], 'J': ['90', '89', '73', '91']}
When I Execute the following code it works correctly:
hassam="CHECK"
list1={i:hassam[i] for i in range(5)}
list1
output:
{0: 'C', 1: 'H', 2: 'E', 3: 'C', 4: 'K'}
but when i execute this:
hassam="CHECK"
list1={hassam[i]:i for i in range(5)}
list1
output:
{'C': 3, 'H': 1, 'E': 2, 'K': 4}
why isnt this:
{'C': 1, 'H': 2, 'E': 3,'C' : 4 ,'K': 5}
For the dictionary :
{0: 'C', 1: 'H', 2: 'E', 3: 'C', 4: 'K'}
the numbers being the key is not same.
But for the dictionary
{'C': 1, 'H': 2, 'E': 3,'C' : 4 ,'K': 5}
python doesn't allow duplicate keys. Therefore the key is updated with the new value.
Here, it showed so because dictionaries cannot have same keys with diffrent values. So try using list1 as a list like:
list1=[{hassam[i]:i} for i in range(5)]
This would give:
[{'C': 0}, {'H': 1}, {'E': 2}, {'C': 3}, {'K': 4}]
Or a tuple instead of individual dictionaries:
list1=[(hassam[i],i) for i in range(5)]
How do I extend the values in a dictionary from a list of dictionaries using the keys as the main constraint, say:
d = {'a': (), 'b': 0, 'c': "", d: ""}
l = [ {'a': (23, 48), 'b': 34, 'c': "fame", d: "who"},
{'a': (94, 29), 'b': 3, 'c': "house", d: "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", d: "stack"},
]
to give
d = {'a': [(23, 48), (94,29), 23,12], 'b': [34, 3, 94],
'c': ["fame", "house", "imap"], 'd': ['who', 'cats', 'stack'] }
code used
for i in l:
d["a"].extend(i.get('a')),
d["b"].extend(i.get('b')),
d["c"].extend(i.get('c')),
d['d'].extend(i.get('d'))
You should initialize d as an empty dict instead, so that you can iterate through l and the key-value pairs to keep appending the values to the sub-list of d at the given keys:
l = [
{'a': (23, 48), 'b': 34, 'c': "fame", 'd': "who"},
{'a': (94, 29), 'b': 3, 'c': "house", 'd': "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", 'd': "stack"},
]
d = {}
for s in l:
for k, v in s.items():
d.setdefault(k, []).append(v)
d becomes:
{'a': [(23, 48), (94, 29), (23, 12)],
'b': [34, 3, 93],
'c': ['fame', 'house', 'imap'],
'd': ['who', 'cats', 'stack']}
If the sub-dicts in l may contain other keys, you can instead initialize d as a dict of empty lists under the desired keys:
l = [
{'a': (23, 48), 'b': 34, 'c': "fame", 'd': "who"},
{'a': (94, 29), 'b': 3, 'c': "house", 'd': "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", 'd': "stack"},
{'e': 'choices'}
]
d = {k: [] for k in ('a', 'b', 'c', 'd')}
for s in l:
for k in d:
d[k].append(s.get(k))
in which case d becomes:
{'a': [(23, 48), (94, 29), (23, 12), None],
'b': [34, 3, 93, None],
'c': ['fame', 'house', 'imap', None],
'd': ['who', 'cats', 'stack', None]}
You can use defaultdict as follow since the default value is an empty list (https://docs.python.org/2/library/collections.html#collections.defaultdict)
import collections
d = collections.defaultdict(list)
keys = ['a', 'b', 'c', 'd']
for i in l:
for k in keys:
d[k].append(i[k])
print(d)
Best regard
d = {'U': 4, '_': 2, 'C': 2, 'K': 1, 'D': 4, 'T': 6, 'Q': 1, 'V': 2, 'A': 9, 'F': 2, 'O': 8, 'J': 1, 'I': 9, 'N': 6, 'P': 2, 'S': 4, 'M': 2, 'W': 2, 'E': 12, 'Z': 1, 'G': 3, 'Y': 2, 'B': 2, 'L': 4, 'R': 6, 'X': 1, 'H': 2}
def __str__(self):
omgekeerd = {}
for sleutel, waarde in self.inhoud.items():
letters = omgekeerd.get(waarde, '')
letters += sleutel
omgekeerd[waarde] = letters
for aantal in sorted(omgekeerd):
return '{}: {}'.format(aantal, ''.join(sorted(omgekeerd[aantal])))
I need to return the value, followed by a ':' and then followed by every letter that has that value.
The problem is that when I use return, it only returns one value instead of every vale on a new line.
I can't use print() because that is not supported by the method str(self).
The return statement ends function execution and specifies a value to
be returned to the function caller.
I believe that your code is terminated too early because of wrong usage of return statement.
What you could do is to store what you would like to return in a seperate list/dictionary and then when everything is done, you can return the new dict/list that you've stored the results in.
If I understood you correctly; This is what might be looking for:
def someFunc():
d = {'U': 4, '_': 2, 'C': 2, 'K': 1, 'D': 4, 'T': 6, 'Q': 1, 'V': 2, 'A': 9,
'F': 2, 'O': 8, 'J': 1, 'I': 9, 'N': 6, 'P': 2, 'S': 4, 'M': 2, 'W': 2, 'E': 12,
'Z': 1, 'G': 3, 'Y': 2, 'B': 2, 'L': 4, 'R': 6, 'X': 1, 'H': 2}
result = {}
for key, value in d.iteritems():
result[value] = [k for k,v in d.iteritems() if v == value]
return result
# call function and iterate over given dictionary
for key, value in someFunc().iteritems():
print key, value
Result:
1 ['K', 'J', 'Q', 'X', 'Z']
2 ['C', 'B', 'F', 'H', 'M', 'P', 'W', 'V', 'Y', '_']
3 ['G']
4 ['D', 'L', 'S', 'U']
6 ['N', 'R', 'T']
8 ['O']
9 ['A', 'I']
12 ['E']
the list is this :
List1 = ['a','b','c','d','e','f','g','h','h','i','j','k','l','m','n']
And I am hoping for the outcome to be where each times the item appears in the list its assigned an integer e.g:
List1 = ['a:1']
without using the 'import counter' module
You could use this list comprehension:
dict((x, List1.count(x)) for x in set(List1))
Example output:
{'d': 1, 'f': 1, 'l': 1, 'c': 1, 'j': 1, 'e': 1, 'i': 1, 'a': 1, 'h': 2, 'b': 1, 'm': 1, 'n': 1, 'k': 1, 'g': 1}
(Edited to match edited question.)
Use a dictionary comprehension and count.
>>> List1 = ['a','b','c','d','e','f','g','h','h','i','j','k','l','m','n']
>>> mapping = {v: List1.count(v) for v in List1}
>>> mapping
{'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1,
'g': 1, 'h': 2, 'i': 1, 'j': 1, 'k': 1, 'l': 1, 'm': 1, 'n': 1}