4

私の辞書にif文を適切に配置するのを誰かが手伝ってくれますか? 私は NY のユーザーにフラグを立て、辞書の最初に来るようにしています。必要な名前で並べ替えることもできますが、NYユーザーにフラグを立てる方法が明確ではありません

names_states = {
  'user1': 'CA',
  'user2': 'NY',
  'user7': 'CA',
  'guest': 'MN',
}


for key in sorted(names_states.iterkeys()):
   2   ...   print "%s :  %s" %(key, names_states[key])
   3   ...
   4   user1 :  CA
   5   user2 :  NY
   6   guest :  MN
   7   user7 :  CA
4

5 に答える 5

4
sorted(names_states.iteritems(), key=lambda x: (x[1] != 'NY', x[0]))
于 2012-05-12T23:55:46.440 に答える
3

これは、ユーザー名を最初のキーとして、州を 2 番目のキーとして並べ替えながら、最初に NY の値を一番上にプッシュするアプローチです。

{'bill': 'NY',
 'frank': 'NY',
 'guest': 'MN',
 'user1': 'CA',
 'user2': 'NY',
 'user7': 'CA'}

def keyFunc(x):
    if names_states[x] == 'NY': 
        return (False, x)
    return (x, names_states[x])

sorted(names_states.iterkeys(), key=keyFunc)

# ['bill', 'frank', 'user2', 'guest', 'user1', 'user7']

注: ここでのアプローチに固執する方が、カスタム関数keyを定義するよりも高速です。cmpkey 関数はアイテムごとに 1 回だけ実行されますが、cmp 関数はすべての組み合わせで実行されます。

于 2012-05-12T23:46:00.413 に答える
2

これはあなたが要求したことを行います-最初にすべてのニューヨーカーが名前でソートされ、次に他のすべての人も名前でソートされます。

names_states = {
    'user1': 'CA',
    'user2': 'NY',
    'user7': 'CA',
    'guest': 'MN',
}

def ny_compare(x, y):
    if names_states[x] == 'NY':
        if names_states[y] == 'NY':
            return cmp(x,y)
        else:
            return -1
    elif names_states[y] == 'NY':
        return 1
    return cmp(x,y)


for key in sorted(names_states.iterkeys(), cmp=ny_compare):
    print "%s :  %s" %(key, names_states[key])
于 2012-05-12T23:45:49.987 に答える
1

タプルアンパッキングを使用すると、より明確になる場合があります

sorted(names_states.iteritems(), key=lambda (name, state): (state != 'NY', name))
于 2012-05-13T01:32:53.073 に答える
0
for key, value in sorted(names_states.iteritems(), 
            key=lambda (key, value): ((0 if value == 'NY' else 1), key)):
    print((key,value))

ここで iteritems() は、辞書内のキーと値のペアに対する反復子を取得します。次に、それらのキーと値のペアを並べ替えることができます。ラムダ式は、あなたが言うようにリストをソートする一連のキーを作成します。これは、最初の要素が値であるかどうかに基づいた数値であるタプルを返すことによって行われ'NY'ます。基本的に、タプルは最初の要素でソートされ、次に 2 番目の要素でソートされるという事実を利用しています。

とは言っても、これはかなり面倒に見え始めているので、もっと冗長でわかりやすい方法を見つけたいと思うかもしれません。

dict をサブクラス化し、必要な順序でキー、値、またはキーと値のペアを公開する追加のメソッドを追加することができます。

そうすれば、次のような単純なものを作成できます。

names_states = MyDict({
  'user1': 'CA',
  'user2': 'NY',
  'user7': 'CA',
  'guest': 'MN',
})

for key, value in names_states.iteritems_with_given_values_first('NY'):
    ...

class MyDict(dict):

    def __init__(self, *args, **kwargs):
        super(MyDict, self).__init__(*args, **kwargs)

    def iteritems_with_given_values_first(self, preferred_value):
        for key, value in sorted(names_states.iteritems(), 
                key=lambda (key, value): ((0 if value == preferred_value else 1), key)):
            yield key, value
于 2012-05-12T23:50:35.270 に答える