Python-dict에서 처음 N 개의 키 : 값 쌍 반환


108

다음 사전을 고려하십시오. d :

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

d (이 경우 N <= 4)에서 처음 N 개의 키 : 값 쌍을 반환하고 싶습니다. 이를 수행하는 가장 효율적인 방법은 무엇입니까?


1
주의. 답변에 많은 잘못된 정보가있는 것 같습니다. 내 테스트에 따르면 단일 솔루션이 list(d.items())[:4]. list ()는 많은 답변에 대한 기본 구현입니다.
— BSalita

답변:


114

a dict는 어떤 키가 먼저 삽입되었는지 기억하지 못 하기 때문에 "처음 n"키 같은 것은 없습니다.

당신이 얻을 수 있는 n 개의 키 - 값 쌍 생각을 :

n_items = take(n, d.iteritems())

이것은의 구현 사용 take로부터 itertools조리법 :

from itertools import islice

def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(islice(iterable, n))

온라인 작업보기 : ideone


Python 3.6 용 업데이트

n_items = take(n, d.items())

42
나는 파이썬 3의 사람들을 위해 iteritems대체되어야 한다고 믿습니다items
— Monica Heddneck

1
@MonicaHeddneck, 훌륭합니다.이 댓글을 추가해 주셔서 감사합니다.
— 칼 베이커

12
초보자- take()어디에서나 파이썬 코드베이스의 일부입니까? 아니면 여기에 대한 답변에서 정의한 기능입니까? 코드베이스의 일부인 것처럼 물어 보면 찾거나 가져올 수 없습니다. :)
— Scott Borden

81

무엇이든 검색하는 매우 효율적인 방법은 목록 또는 사전 이해를 슬라이싱과 결합하는 것입니다. 항목을 주문할 필요가없는 경우 (n 개의 임의 쌍만 원함) 다음과 같은 사전 이해를 사용할 수 있습니다.

# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}

일반적으로 이와 같은 이해는 "for x in y"루프보다 항상 실행 속도가 더 빠릅니다. 또한 .keys ()를 사용하여 사전 키 목록을 만들고 해당 목록을 분할하면 새 사전을 빌드 할 때 불필요한 키를 '건드리지'않도록 할 수 있습니다.

키 (값만)가 필요하지 않은 경우 목록 이해를 사용할 수 있습니다.

first2vals = [v for v in mydict.values()[:2]]

키를 기준으로 정렬 된 값이 필요한 경우에는 그다지 문제가되지 않습니다.

first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]

또는 키가 필요한 경우 :

first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}

2
사전으로 값 쌍되지 목록으로, : 당신이 N 많은 키를 선택하려는 경우 하나는 더 나은 솔루션입니다
— fermat4214

1
@ fermat4214이 명령 중 하나를 실행할 때 전체 사전이 인쇄되면 문제가 있습니까?
— 생명의 테드 테일러

list (mydict) [: 2]는 사전을 정렬 할 필요가없고 처음 2 개의 요소 만 필요하다면 낭비입니다. 사전에 1mil kv 쌍이 있으면 어떻게됩니까? 모든 것을 목록으로 변환하는 것은 비용이 많이 듭니다. Mark Byers의 솔루션이 훨씬 낫습니다.
— JJ

이것이 해결책이되어야합니다!
— Guenter

14

파이썬의 dict는 순서가 지정되지 않았으므로 "처음 N"키를 요청하는 것은 의미가 없습니다.

collections.OrderedDict즉 당신이 필요하다면 클래스를 사용할 수 있습니다. 처음 네 가지 요소를 다음과 같이 효율적으로 얻을 수 있습니다.

import itertools
import collections

d = collections.OrderedDict((('foo', 'bar'), (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')))
x = itertools.islice(d.items(), 0, 4)

for key, value in x:
    print key, value

itertools.islice반복기에서 요소 조각을 느리게 가져올 수 있습니다. 결과를 재사용 할 수있게하려면 다음과 같이 목록이나 다른 것으로 변환해야합니다.

x = list(itertools.islice(d.items(), 0, 4))

게으른 표정이 아닙니다. `list (d.items ()) [: 4]보다 2 배 더 오래 걸립니다
— BSalita

12
foo = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
iterator = iter(foo.items())
for i in range(3):
    print(next(iterator))

기본적으로 뷰 (dict_items)를 반복자로 전환 한 다음 next ()로 반복합니다.


2
환상적인 대답, 이것은이 페이지에서 나를 위해 일하고 읽을 수있는 유일한 대답입니다. 또한 이것이 Python 3에서 작동하는지 확인할 수 있는데, 이전 답변 중 일부는 그렇지 않은 것 같습니다.
— cdahms

7

여기서 보지 못했어요. 정렬되지는 않지만 사전에서 일부 요소를 가져와야하는 경우 가장 간단한 구문입니다.

n = 2
{key:value for key,value in d.items()[0:n]}

7
코드를 시도했지만이 오류가 발생합니다. TypeError: 'dict_items' object is not subscriptable {key:value for key,value in stocks.items()[0:n]} (stocks는 내 사전의 이름입니다)
— Moondra

2
@Moondra-사전 항목을 실행하기 전에 목록으로 변환해야합니다. 위의 코드 줄은 경우 {: 목록에서 키 값 (d.items ())에 대한 값 [n은 0] 키} 작동
— 인 Rajesh Mappu

{A : N for (A, N) in [x for x in d.items ()] [: 4]}
— farid khafizov

6

파이썬 사전에서 상위 N 개 요소를 얻으려면 다음 코드 줄을 사용할 수 있습니다.

list(dictionaryName.items())[:N]

귀하의 경우 다음과 같이 변경할 수 있습니다.

list(d.items())[:4]

3

PEP 0265 참조사전 정렬에 를 . 그런 다음 앞서 언급 한 반복 가능한 코드를 사용합니다.

정렬 된 키-값 쌍에서 더 많은 효율성이 필요한 경우. 다른 데이터 구조를 사용하십시오. 즉, 정렬 된 순서와 키-값 연결을 유지하는 것입니다.

예

import bisect

kvlist = [('a', 1), ('b', 2), ('c', 3), ('e', 5)]
bisect.insort_left(kvlist, ('d', 4))

print kvlist # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]

3

py3에서 이것은 트릭을 할 것입니다.

{A:N for (A,N) in [x for x in d.items()][:4]}

{ 'a': 3, 'b': 2, 'c': 3, 'd': 4}


2

zip을 사용하여 답변을 추가하면됩니다.

{k: d[k] for k, _ in zip(d, range(n))}

1

이것은 귀하의 경우에 '가장 효율적인'것이 무엇인지에 달려 있습니다.

거대한 사전의 반 무작위 샘플을 원하는 경우 필요한만큼 많은 값을 foo사용 foo.iteritems()하고 가져 오면 명시적인 키 또는 항목 목록 생성을 피하는 게으른 작업입니다.

먼저 키를 정렬해야하는 경우 keys = foo.keys(); keys.sort()또는 같은 것을 사용하는 방법이 없습니다 sorted(foo.iterkeys()). 명시적인 키 목록을 작성해야합니다. 그런 다음 첫 번째 N을 슬라이스하거나 반복합니다 keys.

BTW 왜 '효율적인'방식에 관심이 있습니까? 프로그램을 프로파일 링했습니까? 그렇지 않은 경우 명확 하고 이해하기 쉬운 방법 을 . 병목 현상이 발생하지 않고 꽤 잘 할 가능성이 있습니다.


이것은 금융 프로그램에 대한 응용 프로그램이었고 가능한 한 효율적으로 모든 코드 줄을 작성하려고합니다. 나는 프로그램을 프로파일 링하지 않았으며 이것이 병목 현상이 아닐 것이라는 데 동의하지만 기본적으로 효율적인 솔루션을 요청하고 싶습니다. 답장을 보내 주셔서 감사합니다.
— Jason Strimpel 2011

0

여러 가지 방법으로 접근 할 수 있습니다. 주문이 중요한 경우 다음을 수행 할 수 있습니다.

for key in sorted(d.keys()):
  item = d.pop(key)

주문이 문제가되지 않는 경우 다음을 수행 할 수 있습니다.

for i in range(4):
  item = d.popitem()

첫 조각에서 당신은 아마 그것을 호출해야 value보다는 item명확합니다.
— agf

0

사전은 순서를 유지하지 않으므로 상위 N 개의 키 값 쌍을 선택하기 전에 정렬 할 수 있습니다.

import operator
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
#itemgetter(0)=sort by keys, itemgetter(1)=sort by values

이제 다음과 같은 메소드 구조를 사용하여 상위 'N'요소 검색을 수행 할 수 있습니다.

def return_top(elements,dictionary_element):
    '''Takes the dictionary and the 'N' elements needed in return
    '''
    topers={}
    for h,i in enumerate(dictionary_element):
        if h<elements:
            topers.update({i:dictionary_element[i]})
    return topers

상위 2 개 요소를 얻으려면 다음 구조를 사용하십시오.

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
d=return_top(2,d)
print(d)

0

Python 3 이상의 경우 처음 n 개 쌍을 선택하려면

n=4
firstNpairs = {k: Diction[k] for k in list(Diction.keys())[:n]}

0

사전을 고려하다

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

from itertools import islice
n = 3
list(islice(d.items(),n))

islice가 트릭을 할 것입니다 :) 도움이되기를 바랍니다!


0

이것은 매우 우아하지는 않지만 나를 위해 작동합니다.

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

x= 0
for key, val in d.items():
    if x == 2:
        break
    else:
        x += 1
        # Do something with the first two key-value pairs

0

위의 답변 중 몇 가지를 시도했으며 일부는 버전에 따라 다르며 버전 3.7에서 작동하지 않습니다.

또한 3.6 이후 모든 사전은 항목이 삽입되는 순서에 따라 정렬됩니다.

3.6 이후로 사전이 정렬 되었음에도 불구하고 정렬 된 구조로 작업 할 것으로 예상되는 일부 명령문이 작동하지 않는 것 같습니다.

저에게 가장 잘 맞는 OP 질문에 대한 답변입니다.

itr = iter(dic.items())
lst = [next(itr) for i in range(3)]

참고로, 5 배 더 느림lst = list(d.items())[:N]
— BSalita
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.