2017-05-24 19 views
3

파이썬 2에서는 OrderedDict을 사용할 때 목록을 반환 한 keys 메서드를 사용하여 삽입 된 순서대로 키를 가져올 수있었습니다. 그러나 파이썬 3에서 :Python 3에서 OrderedDict - 순서대로 키를 얻는 방법?

rows = OrderedDict() 
rows[0]=[1,2,3] 
rows[1]=[1,2,3] 
image = [rows[k] for k in rows.keys()[:2]] 

를 내가 얻을 :

Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
TypeError: 'odict_keys' object is not subscriptable 

I 예를 here에 대한 조언으로 확실히 list(rows)[:2]을 수행 할 수 있습니다 -하지만이 순서대로 나에게 열쇠를 얻을 보장? 이게 올바른 방법일까요?

UPDATE : 파이썬 2 코드가 더 나은 것 같이 : 물론 여전히 파이썬에서 동일한 오류로 불어

image = [v for v in rows.values()[:2]] 

3

+4

예,'list (rows)'를 사용하면 순서가 보장 된'__iter__'과'__next__'를 사용하기 때문에 키를 순서대로 얻는 올바른 방법입니다. 처음 2 개의 키만 필요하면'list (rows) [: 2]'대신'itertools.islice (rows, 2)'를 생각해 볼 수도 있습니다 ... – mgilson

+0

Thanks @mgilson - 더 빠르다 - 작은 목록을 복사하거나 itertools 모듈을 사용한다. 아마도 대답을 시도 할 것인가? :) –

답변

1

@mglison는 권리입니다. OrderedDict 반복자 프로토콜을 따르기 때문에, 그것은 list()yield에 올바른 순서로 키를 보장 :

그러나 @mglison도 언급 한 것처럼, itertools.islice() 단순히 list 첨자를 사용하는 것보다 더 많은 efficent 될 것이다. timeit 모듈을 사용하여 두 방법을 여러 번 타이밍 한 후에 itertools 방법은 약 2 배 빠릅니다. 여기에 정확한 숫자 :

여러 번 (통지 내가 목록에 islice()의 결과를 주조하고있어) 모두 list(itertools.islice(rows, 2))list(rows.keys())[:2]을 실행하는 평균 시간을 점점 후는, 후자의 방법을 사용하여 약간 빠른 실제 것 같습니다 :

--------------------------------------------------------------- 
| list(itertools.islice(rows, 2)) | 1.5023668839901838 |  
--------------------------------------------------------------- 
| list(rows.keys())[:2]    | 1.495460570215706 |  
--------------------------------------------------------------- 

그러나 두 숫자의 차이가 너무 작기 때문에 어떤 방법을 사용하든별로 차이가 없습니다. 특정 사례에 대해 가장 이해하기 쉬운 방법을 선택하십시오.

+0

그것이 정확히 당신이 한 일이라면 나는 공정한 비교라고 생각하지 않는다 : itertools.islice (rows, 2)는 그 자체로리스트를 만들지 않는다. 그것을'list (itertools.islice (rows, 2))'와 비교할 필요가 있으며, 두 가지 접근법이 그 시점에서 훨씬 더 가까워 질 것으로 생각됩니다. – DSM

+0

@DSM 아, 네가 잘 잡았다. 나는 내 뇌가 어디에 있지 않은가. 코드 스 니펫을 다시 계산하고 내 대답을 업데이트합니다. –

+0

zzzz 시간 코드 zzzz를 추가하십시오 :) - @DSM - 그러나 공정한 비교가 될 수 있도록 순서대로 키를 반복하는 데 관심이 있습니다. –