作为输入,我将获得最多可达n级的列表列表,并且每次都会有所不同。假设,我有一个列表
[[2, 1, 3], 4, [2, 3], 7, 1, [9, [4, 2], 5]]
这里我想对此列表进行排序,预期输出为
[1, 4, [2, 3], [1, 2, 3], 7, [5, [2, 4], 9]]
这里,首先基于元素进行排序,然后基于列表内元素的总和。
码
input_freq = [[2,1,3],4,[2,3],7,1,[9,[4,2],5]]
res = []
def sortFreq(input_freq):
elements = []
list_of_elements = []
for each in input_freq:
if isinstance(each, list):
print "list"
list_of_elements.append(each)
each.sort()
else:
elements.append(each)
elements.sort()
print elements
print list_of_elements
sortFreq(input_freq)
预期产出:
[1, 4, [2, 3], [1, 2, 3], 7, [5, [4, 2], 9]]
但我的代码返回错误的结果:
[[1, 2, 3], [2, 3], [5, 9, [4, 2]]]
答案 0 :(得分:3)
您必须先按照嵌套级别进行操作,然后在递归调用返回时对父级别进行排序。我假设您要返回一个新列表(而不是排序):
def nested_sort(l):
def sort_key(e):
if isinstance(e, list):
return sum(sort_key(inner) for inner in e)
return e
return sorted(
[nested_sort(e) if isinstance(e, list) else e for e in l],
key=sort_key)
排序键必须以递归方式对嵌套列表求和,因此如果您有许多嵌套级别,这可能会很昂贵。因此,根据要汇总的列表的标识添加缓存可能是值得的:
def nested_sort(l, _sum_cache=None):
if _sum_cache is None:
_sum_cache = {}
def sort_key(e):
if isinstance(e, list):
e_id = id(e)
if e_id not in _sum_cache:
_sum_cache[e_id] = sum(sort_key(inner) for inner in e)
return _sum_cache[e_id]
return e
return sorted(
[nested_sort(e, _sum_cache) if isinstance(e, list) else e for e in l],
key=sort_key)
演示:
>>> nested_sort([[2, 1, 3], 4, [2, 3], 7, 1, [9, [4, 2], 5]])
[1, 4, [2, 3], [1, 2, 3], 7, [5, [2, 4], 9]]
答案 1 :(得分:0)
这是一个解决方案,它的好处是只需每次执行一次总和。它也很短:
import operator
def sort_lol(lol):
srtd, sums = zip(*sorted((sort_lol(el) if isinstance(el, list) else (el, el)
for el in lol), key=operator.itemgetter(1)))
return list(srtd), sum(sums)
lst = [[2,1,3],4,[2,3],7,1,[9,[4,2],5]]
print(sort_lol(lst))
# ([1, 4, [2, 3], [1, 2, 3], 7, [5, [2, 4], 9]], 43)
# note that the function returns the sorted list and the total (43 here)