复杂分组列表项

时间:2016-11-10 07:04:48

标签: python django group-by

我需要使用python以Facebook格式显示通知。但发现难以对物品进行分组。以下是查询列表

sample list

通知必须显示如下

  • John更改了名称,代码,产品衬衫描述
  • John更改了产品帽的名称
  • John更改了Variant Code of Hat
  • 迈克改变了产品裤子名称,帽子
  • Kiet更改了Variant XXL Shirt的名称

有没有可能使用python group by?按日期排序?

2 个答案:

答案 0 :(得分:1)

基本上,您需要将行减少为具有相同用户和产品名称值的行。我正在使用字典(默认字典)将用户/产品名称映射到其更改元素的列表。

from collections import defaultdict
# Assuming your datastructure looks like:
rows = [['jeff', 'product', 'name', 'shirt'], ['jeff', 'product', 'code', 'shirt'], ['mike', 'product', 'name', 'trouser']]
user_index = 0
changed_index = 2
product_name_index = 3

delimeter = '&&&'
changed_items = defaultdict(list)
for row in rows:
    key = '%s%s%s' % (row[user_index], delimeter, row[product_name_index])
    changed_items[key].append(row[changed_index])

for key, changed in changed_items.iteritems():
    user, product = key.split(delimeter)
    print('%s changed %s of %s' % (user, ', '.join(changed), product))

如果您希望按顺序排序,则必须使用默认的AND有序字典。您可以使用所述数据结构的此实现:https://stackoverflow.com/a/6190500/3741585

答案 1 :(得分:1)

您可以使用groupby尝试以下方法,这似乎适用于您现有的数据,但可能需要进一步考虑其他边缘情况:

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)))

这将显示以下输出:

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