问题:
我有一个列表列表rowData
,其中包含表格格式的其他列表,即
rowData = [strLabel, intA, intB]
我想根据值rowData
和intA
intB
进行排序
所以,如果
rowData = [ ['hi', 0, 1],
['how', 0, 0],
['ru', 2, 2] ]
我想结束
rowData = [ ['how', 0, 0],
['hi', 0, 1],
['ru', 2, 2] ]
当前解决方案:
目前我有一个单独的列表sums
,对应于第二个和第三个"列的总和"对应于intA
和intB
。我的解决方案:
[rowData[i] for i in [sums.index(j) for j in sorted(sums)]]
这是经过一段时间搜索后对我有意义的唯一方法,但我对其效率低下充满信心,并且想知道与其他(希望是简短的)替代品相比效率是多么低效。
答案 0 :(得分:6)
您可以使用lambda表达式将键参数传递给sort()
和sorted()
函数,该表达式将定义要进行排序的键。
rowData = [ ['hi', 0, 1],
['how', 0, 0],
['ru', 2, 2] ]
rowData.sort(key = lambda x:(x[1]+x[2]))
print rowData
>>> [['how', 0, 0], ['hi', 0, 1], ['ru', 2, 2]]
或者,如果您想保留rowData
的内容,则可以同样方式使用sorted()
:
sortedData = sorted(rowData, key = lambda x:(x[1]+x[2]))
答案 1 :(得分:3)
是的,使用index
几乎总是不好,原因有两个:
sums
对每个值进行线性搜索,使整个算法采用二次时间而不是对数线性。例如,如果您有10000个对象,则需要100000000步,而不是大约13288步。[0, 1, 0].index(0)
,[0, 1, 0].index(1)
和[0, 1, 0].index(0)
将为您提供0, 1, 0
,而非0, 1, 2
。一般来说,解决方法的方法是enumerate
或zip
。
例如,enumerate(sums)
为您提供(index, sum)
对,因此您可以使用sums
对sorted(enumerate(sums), key=itemgetter(1))
值进行排序,然后您可以使用这些索引:
[rowData[i] for i, value in sorted(enumerate(sums), key=itemgetter(1))]
或者您可以zip
将rowData
和sums
合并为(sum, rowData)
对,然后sorted(zip(sums, rowData))
按总和排序这些对,然后您只需提取rowData
s:
[row for s, row in sorted(zip(sums, rowData))]
(或者,或者,您可以将zip
对取回两个单独的列表,然后保留第二个列表。)