Python:将名称分区列为相同大小的子列表

Ben*_*end 7 python group-by

我有一个名单,例如['Agrajag', 'Colin', 'Deep Thought', ... , 'Zaphod Beeblebrox', 'Zarquon'].现在我想将此列表划分为大致相同大小的子列表,以便子组的边界位于名称的第一个字母,例如AF,GL,MP,QZ,而不是A-Fe,Fi-Mo,Mu-Pra ,Pre-Z.

我只能想出一个不考虑子组大小的静态大小的分区:

import string, itertools

def _group_by_alphabet_key(elem):
    char = elem[0].upper()
    i = string.ascii_uppercase.index(char)
    if i > 19:
        to_c = string.ascii_uppercase[-1];
        from_c = string.ascii_uppercase[20]
    else:
        from_c = string.ascii_uppercase[i/5*5]
        to_c = string.ascii_uppercase[i/5*5 + 4]
    return "%s - %s" % (from_c, to_c)

subgroups = itertools.groupby(name_list, _group_by_alphabet_key)
Run Code Online (Sandbox Code Playgroud)

有更好的想法吗?

PS:这可能听起来有点像家庭作业,但它实际上是一个网页,其中成员应该显示在5-10个同等大小的组中.

sen*_*rle 4

这是可能有用的东西。我确信有一种更简单的方法...可能涉及itertools. 请注意,这num_pages仅粗略地确定您实际会获得多少页。

编辑:哎呀!有一个错误——它切断了最后一组!下面的内容应该是固定的,但请注意,最后一页的长度会稍微难以预测。另外,我还添加了.upper()可能的小写名称。

EDIT2:以前定义 letter_groups 的方法效率低下;下面基于字典的代码更具可扩展性:

names = ['Agrajag', 'Colin', 'Deep Thought', 'Ford Prefect' , 'Zaphod Beeblebrox', 'Zarquon']
num_pages = 3

def group_names(names, num_pages):
    letter_groups = defaultdict(list)
    for name in names: letter_groups[name[0].upper()].append(name)
    letter_groups = [letter_groups[key] for key in sorted(letter_groups.keys())]
    current_group = []
    page_groups = []
    group_size = len(names) / num_pages
    for group in letter_groups:
        current_group.extend(group)
        if len(current_group) > group_size:
            page_groups.append(current_group)
            current_group = []
    if current_group: page_groups.append(current_group)

    return page_groups

print group_names(names, num_pages)
Run Code Online (Sandbox Code Playgroud)