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 1
、col 2
、 和自动创建排序列表col 3
,但运行时间太长(超过 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,)
它排在最后。