사전 내 최소값에 해당하는 키를 가져옵니다.


304

파이썬 사전이 있다면 최소값을 포함하는 항목의 키를 어떻게 얻습니까?

min()함수 와 관련이 있다고 생각했습니다 ...

주어진 입력 :

{320:1, 321:0, 322:3}

반환 321합니다.


신고서에 오타가 있습니까? 그렇지 않으면 왜 321입니까? 320이 아니어야합니까?
GreenMatt

3
@myself : 이제 알겠습니다. 원하는 것은 항목 값이 최소 인 항목의 핵심입니다. 다른 사람들이 분명히 나처럼 생각한 것처럼 질문에 더 잘 표현하십시오.
GreenMatt

2
데이터 구조 인식의 날 : 최소 요소 만 쿼리하거나 제거하는 경우 우선 순위 큐 또는 힙 사용을 고려하십시오.
대령 패닉

답변:


596

최고 : min(d, key=d.get)-쓸모없는 lambda간접 레이어 를 삽입 하거나 항목 또는 키를 추출 할 이유가 없습니다 !


5
@ KarelBílek 그것은 예를 들어 [11, 22, 33]사전 대신에 예를 들어 "d"로 목록을 전달했음을 의미합니다 {1: 11, 2:22, 3:33}. 'd.get'은 사전에는 유효하지만 목록에는 유효하지 않습니다.
ToolmakerSteve

9
서로 다른 두 키의 값이 같은 경우 어떻게합니까? 그리고 그들은 둘 다 가장 작은 가치가 있습니까? 어떻게 둘 다 반환 할 수 있습니까?
user3226932

5
dict 값이 목록 인 경우이 기술을 사용할 수 있습니까? ex : d={"a":[10, None], "b":[20, None]}, 여기서 최소값은 d [key] [0]에서 계산됩니까?
TrakJohnson

4
어떻게 작동합니까? min 함수의 종류는 min ()이 개별 값 또는 목록만을 인수로 사용한다고 생각했습니다. 사전의 모든 항목을 어떻게 반복합니까?
azureai

2
min()정렬 된 첫 번째 값의 값을 반환합니다. 키는 값을 정렬하는 방법을 지정합니다. key=d.get목록이 사전 값별로 정렬됨을 의미합니다.
notilas

45

OP가 요청한 솔루션을 실제로 제공하는 답변은 다음과 같습니다.

>>> d = {320:1, 321:0, 322:3}
>>> d.items()
[(320, 1), (321, 0), (322, 3)]
>>> # find the minimum by comparing the second element of each tuple
>>> min(d.items(), key=lambda x: x[1]) 
(321, 0)

사용 d.iteritems()하지만, 더 큰 사전에 더 효율적입니다.


3
람다 대신 사용할 수 있습니다 operator.itemgetter(1).
Philipp

2
대신 lamda 사용 d.get
Texom512

요청한대로 키를 반환하지 않고 (키, 값) 쌍을 반환합니다.
Eric O Lebigot

14

가장 낮은 값을 가진 여러 키의 경우 목록 이해를 사용할 수 있습니다.

d = {320:1, 321:0, 322:3, 323:0}

minval = min(d.values())
res = [k for k, v in d.items() if v==minval]

[321, 323]

동등한 기능 버전 :

res = list(filter(lambda x: d[x]==minval, d))

1
귀하의 답변은 매우 유용하며 다른 사람들은 동의 할 것입니다. 수락 된 답변에서 해당 문제에 대한 여러 의견을 참조하십시오. 그러나 그것을 찾으려면 두 번 돌아와야했습니다. 수락 된 답변에 대한 수정 제안을 고려 하시겠습니까? 당신은 실제로 보완 적입니다.
jmon12


6
>>> d = {320:1, 321:0, 322:3}
>>> min(d, key=lambda k: d[k]) 
321

@SilentGhost, @ blob8108 : 디오! snafu 복사하여 붙여 넣기. 지금 수정했습니다.
Daniel Stutzbach

좋은 해결책이라고 생각하지만 익명 함수는 간접 계층 만 추가합니다 key=d.get.
Eric O Lebigot

6

최소 키가 여러 개이고 단순하게 유지하려는 경우

def minimums(some_dict):
    positions = [] # output variable
    min_value = float("inf")
    for k, v in some_dict.items():
        if v == min_value:
            positions.append(k)
        if v < min_value:
            min_value = v
            positions = [] # output variable
            positions.append(k)

    return positions

minimums({'a':1, 'b':2, 'c':-1, 'd':0, 'e':-1})

['e', 'c']

4

최소값이 여러 개인 지 확실하지 않은 경우 다음을 제안합니다.

d = {320:1, 321:0, 322:3, 323:0}
print ', '.join(str(key) for min_value in (min(d.values()),) for key in d if d[key]==min_value)

"""Output:
321, 323
"""

3

편집 : 이것은 최소 답변이 아닌 최소 키에 대한 OP의 원래 질문에 대한 답변입니다.


keys함수를 사용하여 dict의 키를 얻을 수 있으며 min해당 목록의 최소값을 찾는 데 사용할 수 있습니다.


포스터의 원래 질문이 그랬던 것처럼 명확하지 않았기 때문에 실제로 공감대를받을 자격이 없습니다.
GreenMatt

@ Space_C0wb0y : 아마 당신은 OP가 대답 한 후에 뭔가 다른 것을 의미하도록 그의 질문을 편집했음을 알 수있을 것입니다.
Eli Bendersky

3

동일한 최소값으로 여러 키 문제를 해결하는 또 다른 방법 :

>>> dd = {320:1, 321:0, 322:3, 323:0}
>>>
>>> from itertools import groupby
>>> from operator import itemgetter
>>>
>>> print [v for k,v in groupby(sorted((v,k) for k,v in dd.iteritems()), key=itemgetter(0)).next()[1]]
[321, 323]

2

min반복자와 함께 사용하십시오 (python 3 items대신 iteritems). 람다 대신 람다 itemgetter보다 빠른 from 연산자를 사용하십시오 .

from operator import itemgetter
min_key, _ = min(d.iteritems(), key=itemgetter(1))


1

다음 세 가지 옵션의 성능을 비교했습니다.

    import random, datetime

myDict = {}
for i in range( 10000000 ):
    myDict[ i ] = random.randint( 0, 10000000 )



# OPTION 1

start = datetime.datetime.now()

sorted = []
for i in myDict:
    sorted.append( ( i, myDict[ i ] ) )
sorted.sort( key = lambda x: x[1] )
print( sorted[0][0] )

end = datetime.datetime.now()
print( end - start )



# OPTION 2

start = datetime.datetime.now()

myDict_values = list( myDict.values() )
myDict_keys = list( myDict.keys() )
min_value = min( myDict_values )
print( myDict_keys[ myDict_values.index( min_value ) ] )

end = datetime.datetime.now()
print( end - start )



# OPTION 3

start = datetime.datetime.now()

print( min( myDict, key=myDict.get ) )

end = datetime.datetime.now()
print( end - start )

샘플 출력 :

#option 1
236230
0:00:14.136808

#option 2
236230
0:00:00.458026

#option 3
236230
0:00:00.824048

0

정렬 가능한 클래스를 만들려면 min () 함수에 의해 호출되도록 6 개의 특수 함수를 재정의해야합니다.

이들 방법은 __lt__ , __le__, __gt__, __ge__, __eq__ , __ne__순서가 작거나 같거나 크거나 같거나 크거나 같거나 같거나 같지 않다. 예를 들어 __lt__다음과 같이 구현해야 합니다.

def __lt__(self, other):
  return self.comparable_value < other.comparable_value

다음과 같이 min 함수를 사용할 수 있습니다.

minValue = min(yourList, key=(lambda k: yourList[k]))

이것은 나를 위해 일했습니다.


0
min(zip(d.values(), d.keys()))[1]

zip 함수를 사용하여 값과 키를 포함하는 튜플의 반복자를 작성하십시오. 그런 다음 첫 번째 키를 기준으로 최소값을 취하는 최소 기능으로 래핑하십시오. (값, 키) 쌍을 포함하는 튜플을 반환합니다. [1]의 색인은 해당 키를 얻는 데 사용됩니다.


2
이 코드는 질문에 대답 할 수 있지만,이 코드가 질문에 응답하는 이유 및 / 또는 방법에 대한 추가 컨텍스트를 제공하면 장기적인 가치가 향상됩니다.
β.εηοιτ.βε

@ β.εηοιτ.βε 더 좋습니까?
rajn

-1
# python 
d={320:1, 321:0, 322:3}
reduce(lambda x,y: x if d[x]<=d[y] else y, d.iterkeys())
  321

6
1) 감소는 일반적으로 itertools보다 느립니다. 2) 감소의 대부분의 구현은 일부 또는 전부로 간단하게 수행 할 수 있습니다. 3) GvR의 거대 마우스 피스입니다. 4) 연산자 모듈은 가장 간단한 람다를 불필요하게 만들고 복잡한 람다는 어쨌든 실제 함수로 정의해야합니다. 어쩌면 기능 프로그래밍이 무서울 수도 있습니다. ;)
MikeD

@ miked : 더 말해. gvr은 무엇이며 운영자 모듈은 무엇입니까? 링크를 게시 할 수 있습니까? 나는 다른 사람들을 알고 있을지 모르지만 여전히 파이썬에서 중급입니다. 기꺼이 배우자! :-)
eruciform

GvR은 파이썬의 자비로운 독재자 Guido van Rossum입니다. 다음은 리스 피즘 (map, filter, reduce, lambda)이 파이썬에서 앞으로 많은 자리를 차지하지 않는 이유를 설명 하는 5 살짜리 게시물 입니다. 그 이유는 오늘날에도 여전히 그렇습니다. 연산자 모듈은 멤버 추출 을 대체합니다 . "itemgetter (1)"에 비해 "lambda x : x [1]"은 문자가 길고 이해하는 데 더 오래 걸립니다. 공간이 부족하지만 질문하십시오!
MikeD

@ miked : 사과에 처음 물기를 원하십니까? stackoverflow.com/questions/3292481/…
eruciform

그것들은 실제로 내장 된 것을 다시 구현할 필요가 없습니다 ( min()).
Eric O Lebigot

-8

이것이 당신이 찾고있는 것입니까?

d = dict()
d[15.0]='fifteen'
d[14.0]='fourteen'
d[14.5]='fourteenandhalf'

print d[min(d.keys())]

'14'를 인쇄합니다


8
-1 : 질문 한 내용이 아닙니다. 최소 키로 값을 반환합니다. OP는 최소 값으로 키를 원합니다
Brian S
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.