2017-11-02 1 views
0

발전기를 사용할 때 전달 된 사전을 수정하더라도 발전기가 이전 데이터 구조의 결과를 여전히 제공합니다. 어떻게 해결할 수 있습니까?발전기를 사용할 때 사전을 최신 상태로 유지하는 방법은 무엇입니까?

def min_key_order(adict:dict): 
    for key, value in sorted(adict.items()): 
     yield (key, value) 

d = {1:'a', 2:'x', 4:'m', 8:'d', 16:'f'} 
i = min_key_order(d) 
print(next(i)) 
d.pop(2) 
print(next(i)) 

그리고 그것은 나에게 (1,'a'), (2,'x')를 제공, 심지어 나는 사전에서이 키 팝업있다.

+2

변경 한 사전을 반복 할 수 없습니다. 그건 지원되지 않는 행동입니다. –

+1

그러나'sorted()'함수는 ** 새로운 목록을 생성합니다 **; 이 목록은 원본 dicitonary의 변경 사항을 따르도록 업데이트되지 않습니다. –

+0

이들 중 어느 것도 발전기와 관련이 없으므로'd.pop()'를'for' 루프 안에'sorted (d) '를 넣으면 똑같은 동작을합니다. –

답변

2

발전기가 사전을 반복하지 않습니다. 그것은 새 목록 sorted()가 반환 된 개체 이상 반복한다 : 새로운 목록을 업데이트 할 수 없습니다 사전에서 항목을 제거

>>> d = {1:'a', 2:'x', 4:'m', 8:'d', 16:'f'} 
>>> l = sorted(d.items()) 
>>> d 
{1: 'a', 2: 'x', 4: 'm', 8: 'd', 16: 'f'} 
>>> l 
[(1, 'a'), (2, 'x'), (4, 'm'), (8, 'd'), (16, 'f')] 
>>> d.pop(2) 
'x' 
>>> l 
[(1, 'a'), (2, 'x'), (4, 'm'), (8, 'd'), (16, 'f')] 

을; 그 구조는 사전에 라이브 뷰가 아닙니다. 일에 그 들어

, 당신은 재 분류 사전 각자 반복해야하고, 반복 위치를 추적 할 것 : 이것은 상당히 비효율적이다

def sorted_view(d): 
    pos = 0 
    while pos < len(d): 
     yield sorted(d.items())[pos] 
     pos += 1 

; 정렬은 상대적으로 비용이 많이 드는 작업입니다.

더 효율적인 방법은 정렬 된 순서로 단지 키를 저장하는 것입니다, 다음 키를 계속 사용할 수 테스트 경우 : 당신 을 추가 한 경우

def min_key_order(adict:dict): 
    for key in sorted(adict): 
     if key in adict: 
      yield (key, adict[key]) 

이 그러나 검색하지 않습니다 더 많은 열쇠.

관련 문제