You could try the following approach using groupby
, which seems to work for your existing data but might need further thought for other edge cases:
from itertools import groupby
from datetime import datetime
results = [
["User", "Type", "Changed", "Product Name", "Date"],
["John", "Product", "Name", "Shirt", "1-Jan-17"],
["John", "Product", "Code", "Shirt", "1-Jan-17"],
["John", "Product", "Description", "Shirt", "1-Jan-17"],
["John", "Product", "Name", "Hat", "1-Jan-17"],
["John", "Variant", "Code", "XXL Shirt", "1-Jan-17"],
["Mike", "Product", "Name", "Trouser", "2-Jan-17"],
["Mike", "Product", "Name", "Tie", "3-Jan-17"],
["Kiet", "Variant", "Name", "XXL Shirt", "4-Jan-17"]]
sorted_results = sorted(results[1:], key=lambda x: (datetime.strptime(x[4], '%d-%b-%y'), x[0]))
for k1, g1 in groupby(sorted_results, lambda x: x[0]):
grouped_by_name = list(g1)
v1, v2 = [], []
for k2, g2 in groupby(grouped_by_name, lambda x: (x[1], x[3])): # type, name
v1.append(list(g2))
for k2, g2 in groupby(grouped_by_name, lambda x: (x[1], x[2])): # type, changed
v2.append(list(g2))
if len(v1) < len(v2):
for entry in v1:
entries = [changed for user, ptype, changed, pname, date in entry]
print("{} changed {} of {} {}".format(entry[0][0], ', '.join(entries), entry[0][1], entry[0][3]))
else:
for entry in v2:
entries = [pname for user, ptype, changed, pname, date in entry]
print("{} changed {} of {} {}".format(entry[0][0], entry[0][2], entry[0][1], ', '.join(entries)))
This would display the following output:
John changed Name, Code, Description of Product Shirt
John changed Name of Product Hat
John changed Code of Variant XXL Shirt
Mike changed Name of Product Trouser, Tie
Kiet changed Name of Variant XXL Shirt