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.
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}
I would like to make a matrix that makes a list of nested dictionaries.
But I can't find out how to make a matrix, end even less how to put my values into it.
My dictionary looks like:
{'1': {'3': 0, '2': 1, '5': 1, '4': 0, '6': 29},
'3': {'1': 0, '2': 0, '5': 0, '4': 1, '6': 1},
'2': {'1': 13, '3': 1, '5': 21, '4': 0, '6': 0},
'5': {'1': 39, '3': 0, '2': 1, '4': 0, '6': 14},
'4': {'1': 1, '3': 1, '2': 17, '5': 2, '6': 0},
'6': {'1': 0, '3': 43, '2': 0, '5': 0, '4': 1}}
and it should be ordered in a matrix so it looks like this:
1 2 3 4 5 6
1 - 1 0 0 1 29
2 13 - 1 0 21 0
3 0 0 - 1 0 1
4 1 17 1 - 2 0
5 39 1 0 0 - 14
6 0 0 43 1 0 -
I have only tried to understand how to make a matrix:
table=[[for 0 in range(6)] for j in range[6]]
print table
for d1 in range(6):
for d2 in range(6):
table[d1][d2]=d1+d2+2
print table
But I have a dictionary, not lists. I am really lost.
importpandasas pd
a = pd.DataFrame({'1': {'3': 0, '2': 1, '5': 1, '4': 0, '6': 29},
'3': {'1': 0, '2': 0, '5': 0, '4': 1, '6': 1},
'2': {'1': 13, '3': 1, '5': 21, '4': 0, '6': 0},
'5': {'1': 39, '3': 0, '2': 1, '4': 0, '6': 14},
'4': {'1': 1, '3': 1, '2': 17, '5': 2, '6': 0},
'6': {'1': 0, '3': 43, '2': 0, '5': 0, '4': 1}})
puts into a:
1 2 3 4 5 6
1 NaN 13 0 1 39 0
2 1 NaN 0 17 1 0
3 0 1 NaN 1 0 43
4 0 0 1 NaN 0 1
5 1 21 0 2 NaN 0
6 29 0 1 0 14 NaN
which can be then printed into your format:
print a.to_string(na_rep='-')
printing:
1 2 3 4 5 6
1 - 1 0 0 1 29
2 13 - 1 0 21 0
3 0 0 - 1 0 1
4 1 17 1 - 2 0
5 39 1 0 0 - 14
6 0 0 43 1 0 -
Using str.format():
dic = {'1': {'3': 0, '2': 1, '5': 1, '4': 0, '6': 29},
'3': {'1': 0, '2': 0, '5': 0, '4': 1, '6': 1},
'2': {'1': 13, '3': 1, '5': 21, '4': 0, '6': 0},
'5': {'1': 39, '3': 0, '2': 1, '4': 0, '6': 14},
'4': {'1': 1, '3': 1, '2': 17, '5': 2, '6': 0},
'6': {'1': 0, '3': 43, '2': 0, '5': 0, '4': 1}}
strs = "{0:^2} {1:^2} {2:^2} {3:^2} {4:^2} {5:^2} {6:^2}"
print strs.format(" ", *sorted(dic))
for x in sorted(dic):
print strs.format(x, *(dic[x].get(y, '-') for y in sorted(dic)))
output:
1 2 3 4 5 6
1 - 1 0 0 1 29
2 13 - 1 0 21 0
3 0 0 - 1 0 1
4 1 17 1 - 2 0
5 39 1 0 0 - 14
6 0 0 43 1 0 -
You can also generate the strs like this :
strs = " ".join("{"+"{0}{1}".format(i, ":^2}") for i in range(7))
This works for me. It's not very pythonic, as I don't use list comprehensions and that kind of stuff, but this way is easier to read and understand:
import sys
matrix = {'1': {'3': 0, '2': 1, '5': 1, '4': 0, '6': 29},
'3': {'1': 0, '2': 0, '5': 0, '4': 1, '6': 1},
'2': {'1': 13, '3': 1, '5': 21, '4': 0, '6': 0},
'5': {'1': 39, '3': 0, '2': 1, '4': 0, '6': 14},
'4': {'1': 1, '3': 1, '2': 17, '5': 2, '6': 0},
'6': {'1': 0, '3': 43, '2': 0, '5': 0, '4': 1}}
#print the column index
sys.stdout.write ("\t") # empty tab at the beginning
for col_index in range (1, len(matrix)+1):
sys.stdout.write ("%d\t" % col_index)
print ""
# order the matrix rows, using the dictionary keys
for row_index in sorted (matrix.iterkeys()):
#print the row index
sys.stdout.write (str(row_index)+"\t")
# take each row, and order it by its inner key:
row = matrix[row_index]
ordered_row = sorted (row.iterkeys())
# iterate from 1 to number_of_matrix_rows
for col_index in range (1, len(matrix)+1):
# if the current column exists as a key in
# the row, print it. Otherwise, print "-"
row_item = "-"
if str(col_index) in ordered_row:
row_item = row[str(col_index)]
sys.stdout.write (str(row_item)+"\t")
# print next row
print ""
Here is the python code which will print the matrix on screen. Call prettyPrint(data).
table is a multidimentional array(matrix) with the data.
import string
data = {'1': {'3': 0, '2': 1, '5': 1, '4': 0, '6': 29},
'3': {'1': 0, '2': 0, '5': 0, '4': 1, '6': 1},
'2': {'1': 13, '3': 1, '5': 21, '4': 0, '6': 0},
'5': {'1': 39, '3': 0, '2': 1, '4': 0, '6': 14},
'4': {'1': 1, '3': 1, '2': 17, '5': 2, '6': 0},
'6': {'1': 0, '3': 43, '2': 0, '5': 0, '4': 1}}
def prettyPrint(data):
count = len(data)
table = [[0 for x in xrange(count)] for x in xrange(count)]
print string.ljust(' ', 4),
for j in range(1, count + 1):
print string.ljust(`j`, 4),
print ""
for i in range(1, count + 1):
print string.ljust(`i`, 4),
for j in range(1, count + 1):
#print string.rjust(`j`, 4),
if j != i:
print string.ljust(`data[str(i)][str(j)]`, 4),
table[i-1][j-1] = data[str(i)][str(j)]
else:S
print string.ljust('-', 4),
table[i-1][j-1] = '-'
print ""
print "\nMatrix: \n"
for row in table:
print row
prettyPrint(data)
Output:
>>>
1 2 3 4 5 6
1 - 1 0 0 1 29
2 13 - 1 0 21 0
3 0 0 - 1 0 1
4 1 17 1 - 2 0
5 39 1 0 0 - 14
6 0 0 43 1 0 -
Matrix:
[0, 1, 0, 0, 1, 29]
[13, 0, 1, 0, 21, 0]
[0, 0, 0, 1, 0, 1]
[1, 17, 1, 0, 2, 0]
[39, 1, 0, 0, 0, 14]
[0, 0, 43, 1, 0, 0]
>>>
A function based on #Ashwini Chaudhary's solution using str.format that can take a dict with variable lenght:
def prettyPrint(d,space=5,fill='-'):
strs = ''.join('{{{0}:^{1}}}'.format(str(i),str(space))
for i in xrange(len(d)+1))
std = sorted(d)
print strs.format(" ",*std)
for x in std:
print strs.format(x,*(d[x].get(y,fill) for y in std))
prettyPrint(d)
OUT:
1 2 3 4 5 6
1 - 1 0 0 1 29
2 13 - 1 0 21 0
3 0 0 - 1 0 1
4 1 17 1 - 2 0
5 39 1 0 0 - 14
6 0 0 43 1 0 -
OR:
prettyPrint(d,space=3,fill='0')
OUT:
1 2 3 4 5 6
1 0 1 0 0 1 29
2 13 0 1 0 21 0
3 0 0 0 1 0 1
4 1 17 1 0 2 0
5 39 1 0 0 0 14
6 0 0 43 1 0 0
Probably not a perfect or most effective solution, but it works:
def printMatrix (d):
# get the amount of characters needed for the maximum number
numberWidth = len(str(max(max(v.values()) for v in d.values())))
# function to format the numbers
formatNumber = lambda x: str(x).rjust(numberWidth)
keys = sorted(d.keys())
rows = [' '.join(map(formatNumber, [''] + keys))]
for r in keys:
row = [r]
for k in keys:
row.append(d[r].get(k, '-'))
rows.append(' '.join(map(formatNumber, row)))
print('\n'.join(rows))
Used like this:
>>> d = { ... }
>>> printMatrix(d)
1 2 3 4 5 6
1 - 1 0 0 1 29
2 13 - 1 0 21 0
3 0 0 - 1 0 1
4 1 17 1 - 2 0
5 39 1 0 0 - 14
6 0 0 43 1 0 -
The following one-liner can change your dictionary to a list of list(square matrix):
[[d[str(i)].get(str(j), '-') for j in range(1, 7)] for i in range(1, 7)]
where d is your input dictionary. Based upon that, it's easy to print in any format you desire. BTW, unless this is a school assignment, I don't think printing in any concrete format really matters. Changing dictionary to matrix-like data structure makes more sense. If just for debug's sake, you can use pprint to get a nicer output.
Here is a verbose and flexible code without external libraries, it also returns an usable matrix.
dict_matrix = {'1': {'3': 0, '2': 1, '5': 1, '4': 0, '6': 29},
'3': {'1': 0, '2': 0, '5': 0, '4': 1, '6': 1},
'2': {'1': 13, '3': 1, '5': 21, '4': 0, '6': 0},
'5': {'1': 39, '3': 0, '2': 1, '4': 0, '6': 14},
'4': {'1': 1, '3': 1, '2': 17, '5': 2, '6': 0},
'6': {'1': 0, '3': 43, '2': 0, '5': 0, '4': 1}}
def matricize_dict(a_dict, x_size, y_size):
matrix = []
for i in range(y_size):
line = []
for j in range(x_size):
line.append('-')
matrix.append(line)
for i in range(y_size):
line = dict_matrix[str(i+1)]
for j in range(x_size):
try:
cell = line[str(j+1)]
except KeyError:
pass
else:
matrix[i][j] = cell
for item in matrix:
print(item)
return matrix
matricize_dict(dict_matrix, 6, 6)