Python:将名称列表划分为大小相等的子列表
问题内容:
我有一个名字列表,例如['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)
还有更好的主意吗?
PS:这听起来有点像作业,但实际上是针对网页的,其中成员应显示在5-10个相同大小的组的标签中。
问题答案:
这可能有效。我确信有一种更简单的方法……可能涉及itertools
。请注意,这num_pages
仅大致决定了您实际将获得的页面数。
编辑:哎呀!有一个错误-
它切断了最后一组!下面的内容应该是固定的,但是请注意,最后一页的长度会有些不可预测。另外,我添加.upper()
了可能的小写名称。
EDIT2:以前定义letter_groups的方法效率低下;以下基于dict的代码更具可扩展性:
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)