Python:将名称列表划分为大小相等的子列表
我有一个名字列表,例如 ['Agrajag', 'Colin', 'Deep Thought', ... , 'Zaphod Beeblebrox', 'Zarquon']
。现在我想将此列表划分为大小大致相等的子列表,以便子组的边界位于名称的第一个字母处,例如 AF、GL、MP、QZ,而不是 A-Fe、Fi-Mo、Mu-Pra ,预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 个大小相同的组的选项卡中。
I have a list of names, e.g. ['Agrajag', 'Colin', 'Deep Thought', ... , 'Zaphod Beeblebrox', 'Zarquon']
. Now I want to partition this list into approximately equally sized sublists, so that the boundaries of the subgroups are at the first letter of the names, e.g A-F, G-L, M-P, Q-Z, not A-Fe, Fi-Mo, Mu-Pra, Pre-Z.
I could only come up with a statically sized parition that doesn't take size of the subgroups into account:
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)
Any better ideas?
P.S.: this may sound somewhat like homework, but it actually is for a webpage where members should be displayed in 5-10 tabs of equally sized groups.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是可能有用的东西。我确信有一种更简单的方法......可能涉及
itertools
。请注意,num_pages
仅粗略地确定您实际获得的页面数。编辑:哎呀!有一个错误——它切断了最后一组!下面的内容应该是固定的,但请注意,最后一页的长度会稍微难以预测。另外,我添加了
.upper()
来考虑可能的小写名称。EDIT2:以前定义 letter_groups 的方法效率低下;下面基于字典的代码更具可扩展性:
Here's something that might work. I feel certain there's a simpler way though... probably involving
itertools
. Note thatnum_pages
only roughly determines how many pages you'll actually get.EDIT: Whoops! There was a bug -- it was cutting off the last group! The below should be fixed, but note that the length of the last page will be slightly unpredictable. Also, I added
.upper()
to account for possible lowercase names.EDIT2: The previous method of defining letter_groups was inefficient; the below dict-based code is more scalable:
由于您的
name_list
必须经过排序才能使groupby
正常工作,难道您不能只检查每个第 N 个值并以这种方式构建您的划分吗?使用
"A"
作为最左边的端点,使用"Z"
作为最右边的端点,您可以相应地构建 N 个分区,并且它们都应该具有相同的大小。right_endpoints[0]
。right_endpoints[0]
之后的字符,下一个右端点将是right_endpoints[1]
。您可能遇到的问题是,如果其中两个
right_endpoints
相同怎么办...编辑: 示例
Since your
name_list
has to be sorted forgroupby
to work, can't you just check every Nth value and build your divisions that way?And using
"A"
as your leftmost endpoint and"Z"
as your rightmost endpoint, you can construct the N divisions accordingly and they should all have the same size.right_endpoints[0]
.right_endpoints[0]
, the next right endpoint would beright_endpoints[1]
.The issue you may run into is what if two of these
right_endpoints
are the same...edit: example