I have a Python dictionary as follows:
d = {'1': {'1': 3, '2': 1, '3': 1, '4': 4, '5': 2, '6': 3},
'2': {'1': 3, '2': 3, '3': 1, '4': 2},
'3': {'1': 1, '2': 1, '3': 3, '4': 2, '5': 1, '6': 1, '7': 1},
'4': {'1': 1, '2': 1, '3': 3, '4': 2, '5': 1, '6': 1, '7': 1}}
I have this operation on the dictionary:
D = {}
for ko, vo in d.items():
for ki, vi in vo.items():
for i in range(vi):
D[f'{ko}_{ki}_{i}'] = someFunc(ko, ki, i)
I want to translate it into a one liner with dictionary comprehension as follows:
D = {f'{ko}_{ki}_{i}': someFunc(ko, ki, i) for i in range(vi) for ki, vi in vo.items() for ko, vo in d.items()}
But I get an error
NameError: name 'vi' is not defined
Can someone help me with the correct syntax for achieving this?
The order of the loops has to be reversed.
This is what you're looking for:
D = {f'{ko}_{ki}_{i}': someFunc(ko, ki, i) for ko, vo in d.items() for ki, vi in vo.items() for i in range(vi) }
The for clauses in the list comprehension should appear in the same order as in the equivalent for-loop code. The only thing that "moves" is that the innermost assignment is replaced by an expression at the beginning.
Please see https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/ for details.
Related
I have a pandas series of dicts like this:
print(df['genres'])
0 {'0': '1', '1': '4', '2': '23'}
1 {'0': '1', '1': '25', '2': '4', '3': '37'}
2 {'0': '9'}
print(type(df['genres']))
<class 'pandas.core.series.Series'>
print(type(df['genres'][0]))
<class 'dict'>
I want to count the values to get something like this:
{'1': 2, '4': 2, '9': 1, '23': 1, '25': 1, '37': 1}
I tried the following:
print(Counter(chain.from_iterable(df.genres.values)))
Counter({'0': 3, '1': 2, '2': 2, '3': 1})
print(pd.Series(df['genres']).value_counts())
{'0': '1', '1': '4', '2': '23'} 1
{'0': '1', '1': '25', '2': '4', '3': '37'} 1
{'0': '9'} 1
I think it is pretty easy for someone more experienced than me. But I really don't get it ...
Try:
pd.DataFrame(list(df.genres)).stack().value_counts().to_dict()
Output:
{'1': 2, '4': 2, '37': 1, '9': 1, '23': 1, '25': 1}
Let's suppose that I have a dictionary like that:
input_dict = {'3': 2, '5': 4, '36': 7,'62':6}
and I want to have that as an output:
input_dict = {'3': 9, '5': 4, '6':6}
Basically, I want to do the following things:
Keep only the first character of the keys
If after that some keys are the same then add their values
What is the most efficient way to do this?
You can use a defaultdict and slice the key strings keeping only the first character:
from collections import defaultdict
d = defaultdict(int)
for k,v in input_dict.items():
d[k[0]] += v
print(d)
# defaultdict(int, {'3': 9, '5': 4, '6': 6})
Use this:
new_dict = {}
for key, val in input_dict.items():
if key[0] not in new_dict:
new_dict[key[0]] = val
else:
new_dict[key[0]] += val
Output
{'3': 9, '5': 4, '6': 6}
You could use the get method from a dictionary:
input_dict = {'3': 2, '5': 4, '36': 7, '62': 6}
result = {}
for k, v in input_dict.items():
key = k[0]
result[key] = v + result.get(key, 0)
print(result)
Output
{'3': 9, '5': 4, '6': 6}
i have a text file of numbers like so
text.file
'1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9
i would like to convert this to an array like so :
myary= {'1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
but i want the keys to be a string and the values to be integer
i think i am able to get all of this as a string but that is not what i want
i want it to be seprate
using ast.literal_eval
import ast
txt = "'1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9"
print (ast.literal_eval('{' + txt + '}'))
#{'1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
If you don't want to use literal_eval
str="'1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9"
print({x[0].replace("'", ""):int(x[1]) for x in [y.split(': ') for y in [z for z in str.split(',')]] })
#{'2': 2, '7': 7, '8': 8, '4': 4, '1': 1, '9': 9, '3': 3, '6': 6, '5': 5}
I have a masterDict dictionary with keys "1" through "8" with values set to 0
{'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 0, '8': 0}
I also have anotherDict that i'm using to find the key containing a value closest to another value (i'm doing this multiple times with different values).
An example of one of those other values would be value1 = 900
An example of anotherDict would be:
{'1': 74, '2': 938, '3': 28, '4': 10, '5': 100, '6': 33, '7': 45, '8': 99}
The code i'm using to find the value closest to value1 in anotherDict is:
closestValue1 = key, value = min(anotherDict.items(), key=lambda (_, v): abs(v - value1))
In this case, closestValue1 returns:
{'2': 938}
How do I take this and increment the key 2 value in masterDict by 1?
So, masterDict would then contain:
{'1': 0, '2': 1, '3': 0, '4': 0, '5': 0, '6':0, '7':0, '8': 0}
master_dict = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0, '7': 0, '8': 0}
another_dict = {'1': 74, '2': 938, '3': 28, '4': 10, '5': 100, '6': 33, '7': 45, '8': 99}
target_val = 900
target_key, _ = min(another_dict.items(), key=lambda x: abs(target_value-x[1]))
master_dict[target_key]+=1
print (master_dict)
a="90342"
# this used to generate a dict of each char in a and it indexs
modchar=[{i:a.index(i)} for i in a ]
#modchar=[{'9': 0}, {'0': 1}, {'3': 2}, {'4': 3}, {'2': 4}]
# below produce combination now this combination
def combination(x,n):
return list(itertools.combinations(x,n))
combination(modchar,1)
#output [({'9': 0},), ({'0': 1},), ({'3': 2},), ({'4': 3},), ({'2': 4},)]
combination(modchar,2)
#output [({'9': 0}, {'0': 1}), ({'9': 0}, {'3': 2}), ({'9': 0}, {'4': 3}), ({'9': 0}, {'2': 4}), ({'0': 1}, {'3': 2}), ({'0': 1}, {'4': 3}), ({'0': 1}, {'2': 4}), ({'3': 2}, {'4': 3}), ({'3': 2}, {'2': 4}), ({'4': 3}, {'2': 4})]
combination(modchar,3)
#output [({'9': 0}, {'0': 1}, {'3': 2}), ({'9': 0}, {'0': 1}, {'4': 3}), ({'9': 0}, {'0': 1}, {'2': 4}), ({'9': 0}, {'3': 2}, {'4': 3}),....]
if u look at each result in the list first element is tuple of dict.what i want to do is to combine the dictionary inside the tuple and make it as single dict
i have tried
map(lambda x:dict(x[0],**x[1]),list(itertools.combinations(x,n)))
above works only for tuple of two dicts.
how can i produce a code dynamically it should combine all dicts and produce single dict irrespictive of n value in combination(x,n)
expected output: for n=2
[({'9': 0,'0': 1}) ....]
expected output: for n=3
[({'9': 0,'0': 1,'3': 2})..]
Here's a way to do it:
combos = combinations(modchar,3)
def combineDictTuple(dt):
d = {}
for item in dt:
d.update(item)
return d
newCombos = [combineDictTuple(dt) for dt in combos]
# OUTPUT: [{'9': 0, '0': 1, '3': 2}, {'9': 0, '0': 1, '4': 3}, {'9': 0, '0': 1, '2': 4}, {'9': 0, '3': 2, '4': 3}, {'9': 0, '3': 2, '2': 4}, {'9': 0, '2': 4, '4': 3}, {'0': 1, '3': 2, '4': 3}, {'0': 1, '3': 2, '2': 4}, {'0': 1, '2': 4, '4': 3}, {'3': 2, '2': 4, '4': 3}]
This should do what you want:
>>> def update_with_return(d1, d2):
... d1.update(d2)
... return d1
...
>>> reduce(update_with_return, ({'a': 1}, {'b':2}), dict())
{'a': 1, 'b': 2}