質問

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]))
.

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

役に立ちましたか?

解決

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) ...
.

注意:Year integer として抽出する必要があります(文字列としてではありません)、を変更することができます - - 後者は仕様の「降順」部分を満たすために重要なトリックです。lambdaがまったく同じようにする理由はまったく理由はありません(そして、より読みやすくする)ことができるようにする理由は絶対にありません。

他のヒント

最も簡単な方法は、各キー値を別々にソートすることです。最下位鍵から始めて、最上位まであなたの道を働きます。

だから:

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

これは、逆のフラグを使用してもPythonのソートが常に安定しているため、逆の場合はソートしてからリバース(安定性を失い、反転後に安定性を保持します。

もちろん、たくさんのキー列がある場合、これは数回フルコートするため非効率的です。

あなたは、あなたが望んでいるなら、あなたは本物の逆の種類としてこのように年を変換する必要はありません。

これは、たとえば否定できないもの、たとえば否定することでさえ、すべてのものに働く慣用句です。

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')]
.

アカウントで月の略語と日(見つかった場合)を取るラフな解決策です。

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"はロケールの略語の月名で、ロケールに対処しない場合は辞書を使用できます。

これはアレックスの答えのラムダ版です。私はそれが今ダンカンの答えよりもコンパクトに見えると思いますが、明らかにアレックスの答えの読みやすさがたくさん失われました。

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

読みやすさと効率は通常コンパクトさに好ましいはずです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top