这是根据另一个列表的排序排列对列表进行排序的错误方法吗?

时间:2015-05-24 06:48:53

标签: python list sorting

问题:

我有一个列表列表rowData,其中包含表格格式的其他列表,即

rowData = [strLabel, intA, intB]

我想根据值rowDataintA

总和intB进行排序

所以,如果

rowData = [ ['hi', 0, 1], 
            ['how', 0, 0],
            ['ru', 2, 2] ]

我想结束

rowData = [ ['how', 0, 0], 
             ['hi', 0, 1], 
             ['ru', 2, 2] ]

当前解决方案:

目前我有一个单独的列表sums,对应于第二个和第三个"列的总和"对应于intAintB。我的解决方案:

[rowData[i] for i in [sums.index(j) for j in sorted(sums)]]

这是经过一段时间搜索后对我有意义的唯一方法,但我对其效率低下充满信心,并且想知道与其他(希望是简短的)替代品相比效率是多么低效。

2 个答案:

答案 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几乎总是不好,原因有两个:

  1. 这意味着你必须通过sums对每个值进行线性搜索,使整个算法采用二次时间而不是对数线性。例如,如果您有10000个对象,则需要100000000步,而不是大约13288步。
  2. 如果意味着如果您有任何重复的金额,您将得到错误的结果。例如,[0, 1, 0].index(0)[0, 1, 0].index(1)[0, 1, 0].index(0)将为您提供0, 1, 0,而非0, 1, 2
  3. 一般来说,解决方法的方法是enumeratezip

    例如,enumerate(sums)为您提供(index, sum)对,因此您可以使用sumssorted(enumerate(sums), key=itemgetter(1))值进行排序,然后您可以使用这些索引:

    [rowData[i] for i, value in sorted(enumerate(sums), key=itemgetter(1))]
    

    或者您可以ziprowDatasums合并为(sum, rowData)对,然后sorted(zip(sums, rowData))按总和排序这些对,然后您只需提取rowData s:

    [row for s, row in sorted(zip(sums, rowData))]
    

    (或者,或者,您可以将zip对取回两个单独的列表,然后保留第二个列表。)