按数字位数分组正整数列表:现有实现的更简洁优化方案咨询
优化按数字位数分组的Python实现
嘿,你的思路完全没问题,这段代码确实能完成按数字位数分组的需求,但咱们可以让它更简洁、更符合Python的风格~下面给你几种优化方案:
方案1:用collections.defaultdict简化字典操作
你的代码里手动判断键是否存在的逻辑,其实可以用defaultdict来省去——它会自动为不存在的键创建空列表,代码一下子就清爽了:
from collections import defaultdict def separate_by_digit(int_list): int_dict = defaultdict(list) for num in int_list: digit_count = len(str(num)) int_dict[digit_count].append(num) # 如果需要返回普通字典(而非defaultdict),转成dict即可 return dict(int_dict)
这个版本去掉了多余的len_set,逻辑更直接:直接把每个数字按位数丢进对应的列表就行。
方案2:用数学运算算位数(避免字符串转换)
如果要处理超大规模的数字列表,追求更高性能的话,可以用数学方法代替字符串转换来计算位数——字符串转换虽然直观,但性能上不如纯数学运算:
from collections import defaultdict import math def separate_by_digit(int_list): int_dict = defaultdict(list) for num in int_list: if num == 0: digit_count = 1 else: # 用对数计算位数:10^(n-1) ≤ num <10^n → n = floor(log10(num)) +1 digit_count = math.floor(math.log10(num)) + 1 int_dict[digit_count].append(num) return dict(int_dict)
这里单独处理了0的情况(因为log10(0)会报错),如果你的输入全是正整数(就像示例里的),其实可以跳过这个判断,但加上会更严谨。
方案3:直接返回列表分组(用itertools.groupby)
看你的示例输出是[[1,3], [13], [888], [1004]]这种列表套列表的格式,如果这是你实际需要的输出,那用itertools.groupby会更方便——不过要注意必须先按位数排序,因为groupby只会把连续的相同键元素分组:
from itertools import groupby def separate_by_digit(int_list): # 先按数字位数排序,保证相同位数的元素连续 sorted_list = sorted(int_list, key=lambda x: len(str(x))) # 按位数分组,提取每组的列表 return [list(group) for _, group in groupby(sorted_list, key=lambda x: len(str(x)))]
这个版本直接返回你想要的列表格式,一步到位,非常简洁。
顺便优化你的原代码
其实你的原代码里len_set是多余的,直接判断n是否在int_dict里就可以,原代码可以先简化成这样:
def separate_by_digit(int_list): int_dict = {} for int_ele in int_list: n = len(str(int_ele)) if n not in int_dict: int_dict[n] = [] int_dict[n].append(int_ele) return int_dict
这样去掉了冗余的集合,代码也更紧凑。
总结一下:
- 要字典输出选
defaultdict版本,最简洁; - 要列表分组输出选
groupby版本; - 追求极致性能选数学计算位数的版本。
内容的提问来源于stack exchange,提问作者user715519
相关产品推荐
相关产品推荐

