【问题标题】:Complex grouping list items复杂的分组列表项
【发布时间】:2016-11-10 07:04:47
【问题描述】:

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

通知必须显示如下

  • John 更改了产品衬衫的名称、代码和描述
  • John 更改了产品帽子的名称
  • John 更改了帽子的变体代码
  • Mike 更改了产品名称裤子、帽子
  • Kiet 更改了 XXL 款衬衫的名称

有没有可能使用 python group by 来做到这一点?并按日期订购?

【问题讨论】:

  • 项目所在的python数据结构是什么?二维列表?一本字典?只发一张图片很难回答这个问题
  • @JeffMandell 项目来自 SQLAlchemy 结果,可以转换为列表。

标签: python django group-by


【解决方案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

【讨论】:

  • 它在 sorted_results = 处显示“'module' 对象没有属性 'strptime'”... 有什么想法吗?
  • 奇怪,你用的是哪个版本的 Python?
  • 我使用的是 3.4.4 版本
  • 我可以用time.strptime,让我看看
  • Martin,请提供最后帮助,我无法在 print() 中获取“用户”,您能纠正一下吗?谢谢!
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2023-03-03
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多