如何按子列表的内容对子列表列表进行排序,其中子列表包含字符串和布尔值?

Ade*_*yle 7 python sorting list

我有一个包含数千个子列表的列表。这些子列表中的每一个都包含混合字符串和布尔值的组合,例如:

lst1 = [['k', 'b', False], ['k', 'a', True], ['a', 'a', 'a'], ['a', 'b', 'a'], ['a', 'a' , False], ...]
Run Code Online (Sandbox Code Playgroud)

我想根据子列表的内容对此列表进行排序,例如:

lst2 = [['a', 'a', 'a'], ['a', 'a' , False], ['a', 'b', 'a'], ['k', 'a', True], ['k', 'b', False], ...]
Run Code Online (Sandbox Code Playgroud)

我试过这样排序:

lst2 = sorted([list(sorted(x)) for x in lst1])
print(lst2)
Run Code Online (Sandbox Code Playgroud)

由于某些字段中布尔值与字符串的组合,这不起作用,所以我得到TypeError: '<' not supported between instances of 'bool' and 'str'.

我还尝试了一种蛮力方法,创建所有可能的组合,然后检查它们是否在第一个列表中:

col1 = ['a', 'b', 'c', d, e, f, g, h, i, j, k, ..., True, False]
col2 = ['a', 'b', 'c', d, e, f, g, h, i, j, k, ..., True, False]
col3 = ['a', 'b', 'c', d, e, f, g, h, i, j, k, ..., True, False]
lst2 = list()
for t1 in col1:
    for t2 in col2:
        for t3 in col3:
            test_sublist = [t1, t2, t3]
            if test_sublist in lst1:
            lst2.append(test_sublist)
Run Code Online (Sandbox Code Playgroud)

这种方式效果很好,因为我能够为每一列col 1col 2、 和自动创建排序列表col 3,但运行时间太长(超过 3 天)。

是否有更好的解决方案来对这样的混合字符串/布尔列表进行排序?

Kel*_*ndy 3

它们处理任何长度,而不仅仅是长度 3。并且可以处理任何位置的布尔值,而不仅仅是最后一列。对于键控,它们将每个子列表的每个元素转换为一个元组。


解决方案一:

sorted(lst1, key=lambda s: [(e is False, e is True, e) for e in s])
Run Code Online (Sandbox Code Playgroud)

将字符串变成(False, False, thestring)所以它们先出现。
变成True所以(False, True, True)接下来。
变成False所以(True, False, False)它排在最后。

尽管我以相反的方式思考它,如“首先取消优先级False,然后取消优先级True”。一般形式为key=lambda x: (shall_come_last(x), x).


解决方案2:

sorted(lst1, key=lambda s: [((e is True) + 2 * (e is False), e) for e in s])
Run Code Online (Sandbox Code Playgroud)

将字符串变成(0, thestring)所以它们先出现。
变成True所以(1, True)接下来。
变成False所以(2, False)它排在最后。


解决方案3:

sorted(lst1, key=lambda s: [(0, e) if isinstance(e, str) else (2 - e,) for e in s])
Run Code Online (Sandbox Code Playgroud)

将字符串变成(0, thestring)所以它们先出现。
变成True所以(1,)接下来。
变成False所以(2,)它排在最后。