4

有人可以帮助我在我的 dict 上正确放置 if 语句。我试图标记任何纽约用户,并让他们在字典中排在第一位。我也可以按我需要的名称排序,但不清楚如何标记任何纽约用户

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

这是一种首先将 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这里的方法比定义自定义cmp函数要快。key 函数只会对每个项目运行一次,而 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() 为我们提供了一个遍历字典中键/值对的迭代器。然后我们可以对这些键/值对进行排序。lambda 表达式创建一组键,将按照您所说的对列表进行排序。它通过返回元组来做到这一点,元组的第一个元素是一个基于值是否存在的数字'NY'。基本上,我使用的事实是元组按它们的第一个元素排序,然后是它们的第二个元素,依此类推。

也就是说,这开始看起来很混乱,所以你可能想找到一种更详细但更清晰的方法来做到这一点。

您可能希望继承 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 回答