[python] 사전에서 값으로 키 가져 오기

나는 나이를 찾고 Dictionary일치하는 이름을 보여주는 기능을 만들었습니다 .

dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
for age in dictionary.values():
    if age == search_age:
        name = dictionary[age]
        print name

나는 나이를 비교하고 찾는 방법을 알고 있습니다. 나는 그 사람의 이름을 보여주는 법을 모릅니다. 또한 KeyError5 행 으로 인해 문제가 발생합니다. 정확하지 않다는 것을 알고 있지만 뒤로 검색하는 방법을 알 수 없습니다.



답변

없습니다. dict이런 식으로 사용되지 않습니다.

dictionary = {'george': 16, 'amber': 19}
search_age = input("Provide age")
for name, age in dictionary.items():  # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)


답변

mydict = {'george': 16, 'amber': 19}
print mydict.keys()[mydict.values().index(16)]  # Prints george

또는 Python 3.x에서 :

mydict = {'george': 16, 'amber': 19}
print(list(mydict.keys())[list(mydict.values()).index(16)])  # Prints george

기본적으로 목록에서 사전 값을 분리하고 보유한 값의 위치를 ​​찾은 다음 해당 위치에서 키를 가져옵니다.

에 대한 자세한 keys().values()파이썬 3 : 어떻게 딕셔너리의 값의 목록을 얻을 수 있나요?


답변

이름 나이를 모두 원한다면 .items()주요 (key, value)튜플 을 제공하는 것을 사용해야합니다 .

for name, age in mydict.items():
    if age == search_age:
        print name

for루프 에서 튜플을 두 개의 개별 변수로 압축을 풀고 연령을 일치시킬 수 있습니다.

일반적으로 나이별로 조회를하고 같은 나이를 가진 두 사람이 없다면 사전을 뒤집는 것도 고려해야합니다.

{16: 'george', 19: 'amber'}

그래서 당신은 그냥 수행하여 나이의 이름을 찾을 수 있습니다

mydict[search_age]

내장 유형의 이름 이기 때문에 mydict대신 호출했습니다 . 다른 이름으로 사용해서는 안됩니다.listlist

주어진 나이의 모든 사람들의 목록을 한 줄에 얻을 수도 있습니다.

[name for name, age in mydict.items() if age == search_age]

또는 각 연령마다 한 사람 만있는 경우 :

next((name for name, age in mydict.items() if age == search_age), None)

단지 당신에게 줄 것입니다 None그 나이의 사람이 없다면 입니다.

마지막으로 dict가 길고 Python 2를 .iteritems()사용하는 .items()경우 Cat Plus Plus가 목록에서 사본을 만들 필요가 없으므로 Cat Plus Plus 와 달리 대신 사용 하는 것을 고려해야 합니다.


답변

어떤 방법이 가장 빠르며 어떤 시나리오에 있는지 지적하는 것이 흥미로울 것이라고 생각했습니다.

다음은 2012 년 MacBook Pro에서 실행 한 테스트입니다.

>>> def method1(list,search_age):
...     for name,age in list.iteritems():
...             if age == search_age:
...                     return name
...
>>> def method2(list,search_age):
...     return [name for name,age in list.iteritems() if age == search_age]
...
>>> def method3(list,search_age):
...     return list.keys()[list.values().index(search_age)]

profile.run()각 방법에 대한 결과 100,000 회 :

방법 1 :

>>> profile.run("for i in range(0,100000): method1(list,16)")
     200004 function calls in 1.173 seconds

방법 2 :

>>> profile.run("for i in range(0,100000): method2(list,16)")
     200004 function calls in 1.222 seconds

방법 3 :

>>> profile.run("for i in range(0,100000): method3(list,16)")
     400004 function calls in 2.125 seconds

따라서 이것은 작은 dict의 경우 방법 1이 가장 빠르다는 것을 보여줍니다. 방법 2와 같은 모든 일치 항목과 반대로 첫 번째 일치 항목을 반환하기 때문일 가능성이 높습니다 (아래 참고 참조).


흥미롭게도 2700 개의 항목으로 얻은 dict에 대해 동일한 테스트를 수행하면 매우 다른 결과를 얻습니다 (이번에는 10000 회 실행).

방법 1 :

>>> profile.run("for i in range(0,10000): method1(UIC_CRS,'7088380')")
     20004 function calls in 2.928 seconds

방법 2 :

>>> profile.run("for i in range(0,10000): method2(UIC_CRS,'7088380')")
     20004 function calls in 3.872 seconds

방법 3 :

>>> profile.run("for i in range(0,10000): method3(UIC_CRS,'7088380')")
     40004 function calls in 1.176 seconds

여기에서 방법 3이 훨씬 빠릅니다. dict의 크기를 보여 주면 선택한 방법에 영향을 미칩니다.

참고 : 방법 2는 모든 이름 목록을 반환하는 반면 방법 1과 3은 첫 번째 일치 항목 만 반환합니다. 메모리 사용량을 고려하지 않았습니다. 방법 3이 두 개의 추가 목록 (keys () 및 values ​​())을 만들어 메모리에 저장하는지 확실하지 않습니다.


답변

한 줄 버전 : (i는 오래된 사전, p는 반대로 된 사전)

설명 : i.keys()i.values()각각 사전의 키와 값이 반환이 목록을. zip 기능은 사전을 생성하기 위해 목록을 묶을 수 있습니다.

p = dict(zip(i.values(),i.keys()))

경고 : 값이 해시 가능하고 고유 한 경우에만 작동합니다.


답변

a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

또는 더 나은

{k:v for k, v in a.items() if v == 1}


답변

key = next((k for k in my_dict if my_dict[k] == val), None)