正文
假设现有列表[300,150,75,38,19,9,5,2]
,我想把它划分为两个子列表,并要求两个列表的元素和大致相等,应该如何做?
这是一个很有意思的问题,我们期待的答案应该是:
list1: [300] list2: [150,75,38,19,9,5,2]
在写这篇博客之前,我已经浏览了 Together_CZ 的答案,他的思路是:元素和较大的列表与元素和较小的列表的差值大于元素和较大列表中的最小元素的时候,需要弹出最小元素加入的元素和较小列表当中。
但该答案实际上是对列表进行重分配,而不是“划分”,如果我仅仅只是想将一个列表前后切分成元素和大致相等的两个子列表,并且保持元素顺序不变化,应该怎么做呢?实际上只需要一些小小的改动就可以了。
def list_split(one_list): ''' 将给定的列表划分为元素和大致相当的两个子列表 ''' num_list = copy.deepcopy(one_list[:]) # 原列表深拷贝 first_list = [] # 列表构建 second_list = [] # 列表构建 # ------ 将原列表划分为元素和大致相对的两个子列表 ------ # first_list.append(num_list.pop(0)) # 列表初始化 second_list.append(num_list.pop(-1)) # 列表初始化 while len(num_list) != 0: # 若原列表中还有元素 if sum(first_list) >= sum(second_list): # 若first列表中元素和大于second列表 second_list.insert(0, num_list.pop(-1)) # 在头部插入 else: first_list.append(num_list.pop(0)) # 在尾部添加 return first_list, second_list # 返回 if __name__ == "__main__": first_list, second_list = list_split([300,150,75,38,19,9,5,2]) print(first_list) print(second_list)
输出:
[300] [150,75,38,19,9,5,2]
可以看到,子列表的顺序和在原列表中是一样的。
再试一个元素值间隔比较小的list:
# 代码: first_list, second_list = list_split([300, 299, 298, 297, 296, 295, 294, 293]) print(first_list) print(second_list) # 输出: [300, 299, 298, 297] [296, 295, 294, 293] , 294, 293
再试一个乱序的list:
first_list, second_list = list_split([3, 12, 5, 9, 1, 7, 4]) print(first_list) print(second_list) # 输出: [3, 12, 5] [9, 1, 7, 4]