Python 如何创建此目录列表的聚合表达式?

Python 如何创建此目录列表的聚合表达式?,python,list,dictionary,aggregate,Python,List,Dictionary,Aggregate,我有一个字典列表,表示学生信息系统中某个班级的句点+天数。以下是我要汇总的数据: [ { 'period': { 'name': '1', 'sort_order': 1 }, 'day': { 'name': 'A', 'sort_order': 1 } }, { 'period': {

我有一个字典列表,表示学生信息系统中某个班级的句点+天数。以下是我要汇总的数据:

[
    {
        'period': {
            'name': '1',
            'sort_order': 1
        },
        'day': {
            'name': 'A',
            'sort_order': 1
        }
    },
    {
        'period': {
            'name': '1',
            'sort_order': 1
        },
        'day': {
            'name': 'B',
            'sort_order': 2
        }
    },
    {
        'period': {
            'name': '1',
            'sort_order': 1
        },
        'day': {
            'name': 'C',
            'sort_order': 1
        }
    },
    {
        'period': {
            'name': '3',
            'sort_order': 3
        },
        'day': {
            'name': 'A',
            'sort_order': 1
        }
    },
    {
        'period': {
            'name': '3',
            'sort_order': 3
        },
        'day': {
            'name': 'B',
            'sort_order': 2
        }
    },
    {
        'period': {
            'name': '3',
            'sort_order': 3
        },
        'day': {
            'name': 'C',
            'sort_order': 2
        }
    },
    {
        'period': {
            'name': '4',
            'sort_order': 4
        },
        'day': {
            'name': 'D',
            'sort_order': 3
        }
    }
]
我希望上面的聚合字符串减少为1,3A-c4d。请注意,由对象的排序顺序确定的彼此不相邻的对象由分隔,相邻记录由-分隔

编辑 让我试着详细说明聚合过程。每个类会议对象都包含一个期间和一天。通常每天有5节课,并且在A、B、C、D等之间周期性地交替。因此,如果我有一节课在一天中的第一节课,我们可以表示为1A。如果一节课发生在一天中的第一节和第二节,那么它的原始形式可能是1A、2A,但可以缩短为1-2A

有些课程可能不在相邻的时段或日期。一个类可能在一天的第一节课和第三节课上出现,所以它的缩写形式是1,3A。然而,如果该类是在一天中的第一、第二和第三节课,则可以将其写成1-3A。这也适用于天,所以如果一个类发生在第一、第二和第三阶段,在a、B和C天,那么我们可以把它写成1-3A-C

最后,如果一个类发生在第一、第二和第三个周期,以及a、B和C天,但也发生在D天的第四个周期,它的缩写形式将是1-3A-C4D

我试过的 我要执行的第一步是使用以下功能将会议对象分组到相关子列表中:

def _to_related_lists(list):
    """Given a list of section meeting dicts, return a list of lists, where each sub-list is list of
    related section meetings, either related by period or day"""

    related_list = []
    sub_list = []

    related_values = set()
    for index, section_meeting_object in enumerate(list):
        # starting with empty values list
        if not related_values:
            related_values.add(section_meeting_object['period']['name'])
            related_values.add(section_meeting_object['day']['name'])
            sub_list.append(section_meeting_object)
        elif section_meeting_object['period']['name'] in related_values or section_meeting_object['day']['name'] in related_values:
            related_values.add(section_meeting_object['period']['name'])
            related_values.add(section_meeting_object['day']['name'])
            sub_list.append(section_meeting_object)
        else:
            # no related values found in current section_meeting_object
            related_list.append(sub_list)
            sub_list = []
            related_values = set()
            related_values.add(section_meeting_object['period']['name'])
            related_values.add(section_meeting_object['day']['name'])
            sub_list.append(section_meeting_object)

    related_list.append(sub_list)

    return related_list
返回:

[
    [{
        'period': {
            'sort_order': 1,
            'name': '1'
        },
        'day': {
            'sort_order': 1,
            'name': 'A'
        }
    }, {
        'period': {
            'sort_order': 1,
            'name': '1'
        },
        'day': {
            'sort_order': 2,
            'name': 'B'
        }
    }, {
        'period': {
            'sort_order': 2,
            'name': '2'
        },
        'day': {
            'sort_order': 1,
            'name': 'A'
        }
    }, {
        'period': {
            'sort_order': 2,
            'name': '2'
        },
        'day': {
            'sort_order': 2,
            'name': 'B'
        }
    }],
    [{
        'period': {
            'sort_order': 4,
            'name': '4'
        },
        'day': {
            'sort_order': 3,
            'name': 'C'
        }
    }]
]

如果整个字符串1-3A-c4d是我最后想要的聚合表达式,那么让我们调用1-3A-C和4D子表达式。每个相关的子列表都是一个子表达式,所以我想我应该以某种方式遍历每个子列表并创建子表达式,但我不确定如何做到这一点。

首先,让我们将您的列表定义为d_列表

注意,我使用python本机模块来定义B在A和C之间

import string

agg0 = {}
for d in d_list:
    name = d['period']['name']
    if name not in agg0:
        agg0[name] = []
    day = d['day']
    agg0[name].append(day['name'])

agg1 = {}
for k,v in agg0.items():
    pos_in_alph = [string.ascii_lowercase.index(el.lower()) for el in v]
    allowed_indexes = [max(pos_in_alph),min(pos_in_alph)]
    agg1[k] = [el for el in v if string.ascii_lowercase.index(el.lower()) in allowed_indexes]

agg = {}
for k,v in agg1.items():
    w = tuple(v)
    if w not in agg:
        agg[w] = {'ks':[],'gr':len(agg0[k])>2}
    agg[w]['ks'].append(k)
    print agg[w]

str_ = ''
for k,v in sorted(agg.items(), key=lambda item:item[0], reverse=False):
    str_ += ' {pnames}({dnames})'.format(pnames=('-' if v['gr'] else ',').join(sorted(v['ks'])),
                                         dnames='-'.join(k))

print(str_.strip())
哪个输出1-3A-C4D

在@NathanJones的评论之后,请注意,如果d_列表被定义为

d_list = [
    {'period': {'sort_order': 1, 'name': '1'}, 'day': {'sort_order': 1, 'name': 'A'}},
    ##{'period': {'sort_order': 1, 'name': '1'}, 'day': {'sort_order': 2, 'name': 'B'}},
    {'period': {'sort_order': 1, 'name': '1'}, 'day': {'sort_order': 1, 'name': 'C'}},
    {'period': {'sort_order': 3, 'name': '3'}, 'day': {'sort_order': 1, 'name': 'A'}},
    {'period': {'sort_order': 3, 'name': '3'}, 'day': {'sort_order': 2, 'name': 'B'}},
    {'period': {'sort_order': 3, 'name': '3'}, 'day': {'sort_order': 2, 'name': 'C'}},
    {'period': {'sort_order': 4, 'name': '4'}, 'day': {'sort_order': 3, 'name': 'D'}},
]

上面的代码将打印1,3A-c4d

我一个字也不懂。你的输入和输出之间的关系充其量是令人困惑的。例如,如果B只对应于2和3,而不是1-3,那么输出字符串将如何形成?@asongtoruin在输出中将是1A 2-3A-B排序顺序没有意义?每个day对象中的sort_order字段表示B在A和C之间。当我尝试运行此命令时,我得到了这个错误:AttributeError:module'string'没有属性'lowercase',感谢您将其更新为Python3.0。我不认为它使用排序顺序,因为我的输出是3-1A-C 4。我也不认为这个解决方案会考虑相邻周期/天与非相邻周期/天。
d_list = [
    {'period': {'sort_order': 1, 'name': '1'}, 'day': {'sort_order': 1, 'name': 'A'}},
    ##{'period': {'sort_order': 1, 'name': '1'}, 'day': {'sort_order': 2, 'name': 'B'}},
    {'period': {'sort_order': 1, 'name': '1'}, 'day': {'sort_order': 1, 'name': 'C'}},
    {'period': {'sort_order': 3, 'name': '3'}, 'day': {'sort_order': 1, 'name': 'A'}},
    {'period': {'sort_order': 3, 'name': '3'}, 'day': {'sort_order': 2, 'name': 'B'}},
    {'period': {'sort_order': 3, 'name': '3'}, 'day': {'sort_order': 2, 'name': 'C'}},
    {'period': {'sort_order': 4, 'name': '4'}, 'day': {'sort_order': 3, 'name': 'D'}},
]