Taking this dictionary:
{'local': {'count': 7,
'dining-and-nightlife': {'count': 1,
'bar-clubs': {'count': 1}
},
'activities-events': {'count': 6,
'outdoor-adventures': {'count': 4},
'life-skill-classes': {'count': 2}
}
}}
How do I determine the most relevant match (within a 30% leeway)? For example, activities-events has a count of 6 so 6/7 = 85% and its child outdoor-adventures has a count of 4 out 6 (66%). So from this the most relevant category is outdoor-adventures.
In this example:
{'local': {'count': 11,
'dining-and-nightlife': {'count': 4,
'bar-clubs': {'count': 4}
},
'activities-events': {'count': 6,
'outdoor-adventures': {'count': 4},
'life-skill-classes': {'count': 2}
}
}}
Take both dining-and-nightlife (33%) with bar-clubs (100%) and activities-events (54%) with
outdoor-aventures (66%).
I was hoping the percentage cutoff to be determined by
cutoff = 0.3
The idea here is to determine which category is most relevant removing the smaller results (below a 30%) match.
#F.J answered this question below but now I wish to update the counts in the tree.
Inital Output:
{'local': {'activities-events': {'count': 6,
'life-skill-classes': {'count': 2},
'outdoor-adventures': {'count': 4}},
'count': 11,
'dining-and-nightlife': {'bar-clubs': {'count': 4}, 'count': 4}}}
Post output:
{'local': {'activities-events': {'count': 6,
'life-skill-classes': {'count': 2},
'outdoor-adventures': {'count': 4}},
'count': 10,
'dining-and-nightlife': {'bar-clubs': {'count': 4}, 'count': 4}}}
The following should work, note that this will modify your input dictionary in place:
def keep_most_relevant(d, cutoff=0.3):
for k, v in list(d.items()):
if k == 'count':
continue
if 'count' in d and v['count'] < d['count'] * cutoff:
del d[k]
else:
keep_most_relevant(v)
Examples:
>>> d1 = {'local': {'count': 7, 'dining-and-nightlife': {'count': 1, 'bar-clubs': {'count': 1}}, 'activities-events': {'count': 6, 'outdoor-adventures': {'count': 4}, 'life-skill-classes': {'count': 2}}}}
>>> keep_most_relevant(d1)
>>> pprint.pprint(d1)
{'local': {'activities-events': {'count': 6,
'life-skill-classes': {'count': 2},
'outdoor-adventures': {'count': 4}},
'count': 7}}
>>> d2 = {'local': {'count': 11, 'dining-and-nightlife': {'count': 4, 'bar-clubs': {'count': 4}}, 'activities-events': {'count': 6, 'outdoor-adventures': {'count': 4}, 'life-skill-classes': {'count': 2}}}}
>>> keep_most_relevant(d2)
>>> pprint.pprint(d2)
{'local': {'activities-events': {'count': 6,
'life-skill-classes': {'count': 2},
'outdoor-adventures': {'count': 4}},
'count': 11,
'dining-and-nightlife': {'bar-clubs': {'count': 4}, 'count': 4}}}
def matches(match, cutoff):
total = float(match['count'])
for k in match:
if k == 'count':
continue
score = match[k]['count'] / total
if score >= cutoff:
yield (k, score)
m = list(matches(match[k], cutoff))
if m: yield max(m, key=lambda (c, s): s)
def best_matches(d, cutoff):
for k in d:
for m in matches(d[k], cutoff):
yield m
Test 1
>>> d = {'local': {'count': 7,
'dining-and-nightlife': {'count': 1,
'bar-clubs': {'count': 1}
},
'activities-events': {'count': 6,
'outdoor-adventures': {'count': 4},
'life-skill-classes': {'count': 2}
}
}}
>>> print list(best_matches(d, 0.3))
[('activities-events', 0.8571428571428571), ('outdoor-adventures', 0.66666666666666663)]
Test 2
>>> d = {'local': {'count': 11,
'dining-and-nightlife': {'count': 4,
'bar-clubs': {'count': 4}
},
'activities-events': {'count': 6,
'outdoor-adventures': {'count': 4},
'life-skill-classes': {'count': 2}
}
}}
>>> print list(best_matches(d, 0.3))
[('dining-and-nightlife', 0.36363636363636365), ('bar-clubs', 1.0), ('activities-events', 0.54545454545454541), ('outdoor-adventures', 0.66666666666666663)]
Related
This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed 1 year ago.
{'KRW-SOL': {'count': 3, 'tradeAmount': 437540},
'KRW-LOOM': {'count': 78, 'tradeAmount': 21030768},
'KRW-ONT': {'count': 14, 'tradeAmount': 947009},
'KRW-FCT2': {'count': 1, 'tradeAmount': 491935},
'KRW-DKA': {'count': 30, 'tradeAmount': 12053758}
I want to sort by count or tradeAmount
i want like this
{'KRW-LOOM': {'count': 78, 'tradeAmount': 21030768},
'KRW-DKA': {'count': 30, 'tradeAmount': 12053758}
'KRW-ONT': {'count': 14, 'tradeAmount': 947009},
'KRW-SOL': {'count': 3, 'tradeAmount': 437540},
'KRW-FCT2': {'count': 1, 'tradeAmount': 491935}}
sorted(cdDict.items(), key=lambda item: item[1]['tradeAmount'], reverse=True)
you can do something like below
x = {'KRW-SOL': {'count': 3, 'tradeAmount': 437540},
'KRW-LOOM': {'count': 78, 'tradeAmount': 21030768},
'KRW-ONT': {'count': 14, 'tradeAmount': 947009},
'KRW-FCT2': {'count': 1, 'tradeAmount': 491935},
'KRW-DKA': {'count': 30, 'tradeAmount': 12053758}} #input
# new dict sorted by count
y = {k: v for k, v in sorted(x.items(), key=lambda item: item[1]['count'],reverse=True)}
print(y)
If you want sort by tradeAmount then,
y = {k: v for k, v in sorted(x.items(), key=lambda item: item[1]['tradeAmount'],reverse=True)}
print(y)
The Following Data is I am getting from Database i want to make table in html with this data
[{'id': 1}, {'e': 2}, {'i': 3}, {'id': 12}, {'e': 12}, {'i': 23},
{'id': 13}, {'e': 3}, {'i': None}, {'id': 14}, {'e': 23},
{'i': None}, {'id': 123}, {'e': 123}, {'i': 123}]
data = [{'id': 1}, {'e': 2}, {'i': 3}, {'id': 12}, {'e': 12}, {'i': 23},
{'id': 13}, {'e': 3}, {'i': None}, {'id': 14}, {'e': 23},
{'i': None}, {'id': 123}, {'e': 123}, {'i': 123}]
def chunker(seq, size):
# from: https://stackoverflow.com/a/434328/11384184
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
print(f"|id|e|i|")
for id_obj, e_obj, i_obj in chunker(data, 3):
print(f"|{id_obj['id']}|{e_obj['e']}|{i_obj['i']}|")
# |id|e|i|
# |1|2|3|
# |12|12|23|
# |13|3|None|
# |14|23|None|
# |123|123|123|
I just printed the result, but it should be simple to generate the corresponding HTML from there.
I need some help with some code where it needs to go into the log file and it should look like this:
I have the dictonary which holds the count value and the keys which is the event id, but I want to display it like that but I do not know how to since it comes out all at once and it does not print individually instead of 1 by 1 and I have used a nested dictionary to do this.
This is an example of the dictionary which holds the count vals and keys which need to be printed.
eventIDs = {1102: {'count': 0}, 4611: {'count': 0}, 4624: {'count': 0}, 4634: {'count': 0}, 4648: {'count': 0}, 4661: {'count': 0},
4662: {'count': 0}, 4663: {'count': 0}, 4672: {'count': 0}, 4673: {'count': 0}, 4688: {'count': 0}, 4698: {'count': 0},
4699: {'count': 0}, 4702: {'count': 0}, 4703: {'count': 0}, 4719: {'count': 0}, 4732: {'count': 0}, 4738: {'count': 0},
4742: {'count': 0}, 4776: {'count': 0}, 4798: {'count': 0}, 4799: {'count': 0}, 4985: {'count': 0}, 5136: {'count': 0},
5140: {'count': 0}, 5142: {'count': 0}, 5156: {'count': 0}, 5158: {'count': 0}}
This is the code I have tried:
def log_output():
with open('path' + timeStamp + '.txt', 'a') as VisualiseLog:
event_id = list{eventIDs.keys()}
event_count = list(eventIDs.values)
for item in eventIDs:
print(f'Event ID: {event_id}')
VisualiseLog.write('Event ID: {event_id}')
print(f'Event Count: {event_count}')
VisualiseLog.write(f'Event Count: {event_count}')
Try this code:
eventIDs = {
1102: {'count': 0},
4611: {'count': 0}
}
timeStamp = "1234"
def log_output():
with open('path' + timeStamp + '.txt', 'a') as VisualiseLog:
for id in eventIDs:
count = eventIDs[id]['count']
print(f'Event ID: {id}')
VisualiseLog.write(f'Event ID: {id}\n')
print(f'Event Count: {count}')
VisualiseLog.write(f'Event Count: {count}\n\n')
log_output()
# Outputs:
# Event ID: 1102
# Event Count: 0
#
# Event ID: 4611
# Event Count: 0
I have a list of id's sorted in a proper oder:
ids = [1, 2, 4, 6, 5, 0, 3]
I also have a list of dictionaries, sorted in some random way:
rez = [{'val': 7, 'id': 1}, {'val': 8, 'id': 2}, {'val': 2, 'id': 3}, {'val': 0, 'id': 4}, {'val': -1, 'id': 5}, {'val': -4, 'id': 6}, {'val': 9, 'id': 0}]
My intention is to sort rez list in a way that corresponds to ids:
rez = [{'val': 7, 'id': 1}, {'val': 8, 'id': 2}, {'val': 0, 'id': 4}, {'val': -4, 'id': 6}, {'val': -1, 'id': 5}, {'val': 9, 'id': 0}, {'val': 2, 'id': 3}]
I tried:
rez.sort(key = lambda x: ids.index(x['id']))
However that way is too slow for me, as len(ids) > 150K, and each dict actually had a lot of keys (some values there are strings). Any suggestion how to do it in the most pythonic, but still fastest way?
You don't need to sort because ids specifies the entire ordering of the result. You just need to pick the correct elements by their ids:
rez_dict = {d['id']:d for d in rez}
rez_ordered = [rez_dict[id] for id in ids]
Which gives:
>>> rez_ordered
[{'id': 1, 'val': 7}, {'id': 2, 'val': 8}, {'id': 4, 'val': 0}, {'id': 6, 'val': -4}, {'id': 5, 'val': -1}, {'id': 0, 'val': 9}, {'id': 3, 'val': 2}]
This should be faster than sorting because it can be done in linear time on average, while sort is O(nlogn).
Note that this assumes that there will be one entry per id, as in your example.
I think you are on the right track. If you need to speed it up, because your list is too long and you are having quadratic complexity, you can turn the list into a dictionary first, mapping the ids to their respective indices.
indices = {id_: pos for pos, id_ in enumerate(ids)}
rez.sort(key = lambda x: indices[x['id']])
This way, indices is {0: 5, 1: 0, 2: 1, 3: 6, 4: 2, 5: 4, 6: 3}, and rez is
[{'id': 1, 'val': 7},
{'id': 2, 'val': 8},
{'id': 4, 'val': 0},
{'id': 6, 'val': -4},
{'id': 5, 'val': -1},
{'id': 0, 'val': 9},
{'id': 3, 'val': 2}]
I am trying to replace list element value with value looked up in dictionary how do I do that?
list = [1, 3, 2, 10]
d = {'id': 1, 'val': 30},{'id': 2, 'val': 53}, {'id': 3, 'val': 1}, {'id': 4, 'val': 9}, {'id': 5, 'val': 2}, {'id': 6, 'val': 6}, {'id': 7, 'val': 11}, {'id': 8, 'val': 89}, {'id': 9, 'val': 2}, {'id': 10, 'val': 4}
for i in list:
for key, v in d.iteritems():
???
???
so at the end I am expecting:
list = [30, 1, 53, 4]
thank you
D2 = dict((x['id'], x['val']) for x in D)
L2 = [D2[x] for x in L]
td = (
{'val': 30, 'id': 1},
{'val': 53, 'id': 2},
{'val': 1, 'id': 3},
{'val': 9, 'id': 4},
{'val': 2, 'id': 5},
{'val': 6, 'id': 6},
{'val': 11, 'id': 7},
{'val': 89, 'id': 8},
{'val': 2, 'id': 9},
{'val': 4, 'id': 10}
)
source_list = [1, 3, 2, 10]
final_list = []
for item in source_list:
for d in td:
if d['id'] == item:
final_list.append(d['val'])
print('Source : ', source_list)
print('Final : ', final_list)
Result
Source : [1, 3, 2, 10]
Final : [30, 1, 53, 4]