2010-11-28 2 views
3

다음과 같은 사전이 있습니다. 키 값 쌍 또는 사용자 이름 :여러 속성을 정렬하는 파이썬

d = {"user2":"Tom Cruise", "user1": "Tom Cruise"} 

내 문제는 내가 이름으로 다음을 정렬 할 필요가있다 이름을하지만, 여러 사용자가 위와 같이 동일한 이름을 포함하는 경우, 내가 그들의 이름으로 사람들을 분류 할 필요가있다. 정렬 된 함수를 찾았지만 cmp 매개 변수와 람다를 이해하지 못합니다. 만약 누군가가 그것들을 설명하고 이것을 도와 주면 좋을 것입니다! 감사합니다 :)

답변

6

cmp은 노화입니다. lambda이 기능을 수행합니다.

sorted(d.iteritems(), key=operator.itemgetter(1, 0)) 
+0

것은이 아닌 연산자와 같은 라이브러리를 가져올 수 내 클래스와 메신저에 대한 할당의 일부입니다. 그것의 유일한 builtin funcitons. 나는 네가 무엇을 얻고 있는지 이해하고 즉흥적으로 노력했다. 나는 "sorted (l, key = lambda l : (l [0], l [1]))"을 사용했는데 이것이 당신이 말한 것과 동일하다고 생각합니까? – 1337holiday

+0

아닙니다. 'lambda x : (x [1], x [0])' –

+0

이 함수는 이름을 정렬하지만 이름이 같으면 사용자 이름을 정렬하거나 동일한 위치를 유지합니까? 이름이 같으면 사용자 이름별로 정렬해야합니다. 고마워! – 1337holiday

5

난 그냥 이그나시오 바스케스 - 에이 브람스의 대답에 자세히 설명하겠습니다. cmp은 더 이상 사용되지 않습니다. 사용하지 마십시오. 대신 key 속성을 사용하십시오.

lambda이 기능을합니다. 이것은 표현식이므로 보통 def 문은 사용할 수 없지만 본문은 단일 표현식으로 제한됩니다.

my_func = lambda x: x + 1 

x를 하나의 인자를 가지고 x + 1을 반환하는 함수를 정의합니다. lambda x, y=1: x + yx 인수를 취하는 함수를 정의합니다. 선택적인 y 인수는 기본값 1을 사용하고 x + y을 반환합니다. 보시다시피 표현식이고 본문의 단일 표현식으로 제한된다는 점을 제외하면 실제로는 def 문과 같습니다.

key 특성의 목적은 정렬 할 시퀀스의 각 요소에 대해 sorted을 호출하여 비교할 값을 사용한다는 것입니다.

list_ = ['a', 'b', 'c'] 
sorted(list_, key=lambda x: 1) 

가설적인 예를 보려면 나머지를 읽으십시오. 이 글을 쓰기 전에 문제를 자세히 살펴 보지 않았습니다. 그것은 여전히 ​​교육적 일 것이지만 나는 그것을 떠날 것이다. 우리는 정말 훨씬 더

  1. 때문에 당신이 할 수없는 종류의 dict의 말할 수 없다. dicts s의 목록이 있습니까? 우리는 그것을 분류 할 수 있습니다.
  2. username 키가 표시되지 않았습니다.

나는 당신이 내가 톰 크루즈보다 더 굉장 해요 확인하고 싶었다면

users = [{'name': 'Tom Cruise', 'username': user234234234, 'reputation': 1}, 
     {'name': 'Aaron Sterling', 'username': 'aaronasterling', 'reputation': 11725}] 

같은 것이 있다고 가정합니다, 당신은 할 수 :

sorted(users, key=lambda x: x['reputation']) 

이를 목록의 각 사전에 대해 'reputation' 값을 반환하는 함수를 전달합니다. 그러나 lambdas은 더 느려질 수 있습니다. 대부분의 시간은 operator.itemgetter입니다.

operator.itemgetter은 일련의 키를 가져 와서 객체를 취하고 인수 값의 튜플을 반환하는 함수를 반환합니다.

그래서 f = operator.itemgetter('name', 'username')는 차이가 원칙적으로 훨씬 더 빨리 실행해야하고 추한 lambda 표현에서 볼 필요가 없다는 것입니다 lambda d: (d['name'], d['username'])으로 기본적으로 동일한 기능을 반환합니다.

그래서 이그나시오 바스케스 - 에이 브람스 제안 정확히 어떤 단지

sorted(list_of_dicts, operator.itemgetter('name', 'username')) 

을 사용자 이름 다음 이름으로 dict의 목록을 정렬합니다.

+0

그것은 내게 열쇠처럼 보이는 사용자 이름이며, 값은 실제 이름입니다. –

+0

@ 이그나시오 - 맞아. 어떻게 든 당신의 솔루션에있는'iteritems'를 놓쳤습니다. – aaronasterling

+0

OP는 dict을 "Key value pairs 또는 username : name"으로 지정하지만 편집되었을 수도 있습니다. 처음에는 그것을 놓쳤습니다. –

0

dict을 정렬 할 수 없다는 것을 알아야합니다. 하지만 파이썬 2.7 & 3.1이 클래스 collections.OrderedDict 있습니다.

그래서,

>>> from collections import OrderedDict 
>>> d=OrderedDict({'D':'X','B':'Z','C':'X','A':'Y'}) 
>>> d 
OrderedDict([('A', 'Y'), ('C', 'X'), ('B', 'Z'), ('D', 'X')]) 
>>> OrderedDict(sorted((d.items()), key=lambda t:(t[1],t[0]))) 
OrderedDict([('C', 'X'), ('D', 'X'), ('A', 'Y'), ('B', 'Z')]) 
+0

실제로 실제로 문제가되지 않는다면, 내가 필요한 것은 사람의 이름과 사용자 이름을 말하면 이름을 정렬해야하지만 둘 이상의 사람들이 같은 이름을 가진다면 문제가 발생한다는 것입니다. 그 사람들을 사용자 이름 (그 사람들 만)으로 분류하십시오. – 1337holiday