3

Python で次のタプルのリストを並べ替える必要があります。

ListOfTuples = [('10', '2010 Jan 1;', 'Rapoport AM', 'Role of antiepileptic drugs as preventive agents for migraine', '20030417'), ('21', '2009 Nov;', 'Johannessen SI', 'Antiepilepticdrugs in epilepsy and other disorders--a population-based study of prescriptions', '19679449'),...]

私の目的は、降順(listOfTuples[2]) と昇順の作成者 (listOfTuples[2]) で並べることです。

sorted(result, key = lambda item: (item[1], item[2]))

しかし、うまくいきません。ソートの安定性を得るにはどうすればよいですか?

4

5 に答える 5

4
def descyear_ascauth(atup):
  datestr = atup[1]
  authstr = atup[2]
  year = int(datestr.split(None, 1)[0])
  return -year, authstr

... sorted(result, key=descyear_ascauth) ...

注:符号を変更できるように、年を (文字列ではなく)整数として抽出する必要があります。後者は、仕様の「降順」部分を満たすための重要なトリックです。すべてを a 内に詰め込むことは可能ですが、 aが同様に機能する (そしてはるかに読みやすい) 場合、そうして読みやすさをさらに犠牲にする理由はまったくありません。lambdadef

于 2010-07-24T15:07:52.413 に答える
2

最も簡単な方法は、各キー値を個別にソートすることです。最も重要でないキーから始めて、最も重要なキーに向かって作業を進めます。

したがって、この場合:

import operator
ListOfTuples.sort(key=operator.itemgetter(2))
ListOfTuples.sort(key=lambda x: x[1][:4], reverse=True)

これが機能するのは、reverse フラグを使用した場合でも Python のソートが常に安定しているためです。

もちろん、キー列が多数ある場合、完全な並べ替えを数回行うため、これは非効率的です。

このように年を数値に変換する必要はありません。必要に応じて変換できますが、正真正銘の逆の並べ替えです。

于 2010-07-24T15:43:31.087 に答える
0

これがアレックスの答えのラムダ版​​です。現在、ダンカンの回答よりもコンパクトに見えると思いますが、明らかにアレックスの回答の読みやすさの多くが失われています。

sorted(ListOfTuples, key=lambda atup: (-int(atup[1].split(None, 1)[0]), atup[2]))

通常、コンパクトさよりも読みやすさと効率性を優先する必要があります。

于 2010-07-25T10:07:38.493 に答える
0

これは、文字列など、否定できないものであっても、すべてに有効なイディオムです。

data = [ ('a', 'a'), ('a', 'b'), ('b','a') ]

def sort_func( a, b ):
    # compare tuples with the 2nd entry switched
    # this inverts the sorting on the 2nd entry
    return cmp( (a[0], b[1]), (b[0], a[1]) ) 

print sorted( data )                    # [('a', 'a'), ('a', 'b'), ('b', 'a')]
print sorted( data, cmp=sort_func )     # [('a', 'b'), ('a', 'a'), ('b', 'a')]
于 2010-07-24T15:42:36.000 に答える
0

これは、月の省略形と日 (見つかった場合) を考慮した大まかな解決策です。

import time
import operator

def sortkey(seq):
    strdate, author = seq[1], seq[2]
    spdate = strdate[:-1].split()
    month = time.strptime(spdate[1], "%b").tm_mon
    date = [int(spdate[0]), month] + map(int, spdate[2:])
    return map(operator.neg, date), author  

print sorted(result, key=sortkey)

"%b" はロケールの省略された月名です。ロケールを扱いたくない場合は、辞書を使用できます。

于 2010-07-24T15:50:33.970 に答える