如何对嵌套列表的所有级别进行排序?

时间:2018-04-05 05:25:23

标签: python

我有一个表,我想使用"深度"转换为缩进的大纲文档。列作为缩进值和" pos"列作为每个元素在层次结构级别内的相对位置

所以,这个:this

转换为:table

我能够将表解析为python字典:

d = {
223:{'name':'fruit', 'pos':'1',
    634:{'name':'apple', 'pos':'1',
        945:{'name':'red','pos':'2'},
        306:{'name':'round','pos':'1'},
        847:{'name':'sweet','pos':'3'},
        },
    835:{'name':'banana', 'pos':'3',
        751:{'name':'long','pos':'1'},
        607:{'name':'yellow','pos':'2'},
        },
    515:{'name':'orange', 'pos':'2',
        397:{'name':'orange','pos':'2'},
        248:{'name':'round','pos':'1'},
        },
    }
}

我知道如果它没有嵌套,如何对列表或字典进行排序:

d = {
223:{'name':'apple', 'pos':'1'},
945:{'name':'banana','pos':'3'},
847:{'name':'orange','pos':'2'},
}

sort = sorted(d.keys(), key=lambda x: (d[x]['pos']))

但令我困惑的是如何遍历嵌套级别并在每个级别上进行排序。

1 个答案:

答案 0 :(得分:1)

首先,你有相同级别的字符串和列表。 Python不会让你比较这些:

>>> 'abc' < [1]
TypeError: '<' not supported between instances of 'str' and 'list'

如果您想要对这些内容做出规则,可以编写key function来应用该规则。例如,假设我们想要在字符串之前对列表进行排序。我们可以对每个元素x进行排序,就像它是(type(x).__name__, x)

一样
>>> ('str', 'abc') < ('list', [1])
False

有点hacky,但它确实有效,而且由于你没有说明你想如何处理这个问题,我将继续使用该关键功能。

对于您的实际答案,您需要添加该关键函数以将int(lst[1])用于2元素列表,或类似的东西(您不清楚如何区分“特殊” “列表和普通嵌套的列表,但我会留给你做的。

现在,我们只需要递归排序。

如果你想在原地进行,你只需对列表进行排序,然后,对于每个元素,如果它是一个列表,则对其进行嵌套排序。同样,你会想要添加一些特殊的规则 - 包含那些2元素列表,但我不确定你想要什么规则,所以你可以自己解决。

您可能希望更改内容以对每个可变序列进行排序,而不仅仅是列表,或者......以及任何看似合适的序列。

def nested_sort(lst):
    lst.sort(key=lambda x: (type(x).__name__, x))
    for elem in lst:
        if isinstance(elem, list):
            nested_sort(elem)

如果您想要一个排序副本,那么递归就更容易了。同样,你必须为特殊情况列表编写自己的代码,现在你有更多选项可以将类型作为嵌套处理(例如,除了字符串类型之外的所有序列?),但这里的基本思想是:< / p>

def nested_sorted(lst):
    if not isinstance(lst, list): return lst
    return sorted(map(nested_sorted, lst), 
                  key=lambda x: (type(x).__name__, x))