2013-08-07 3 views
1

defaultdictad hocdefault_factory과 함께 사용하면 기꺼이 더 적합합니다. default_factory[0,0]입니다. 내 defaultdict는 예기치 않은 동작 (내가 기대하지 않았다 적어도 동작을)이, defaultdict constant_factory가 예상대로 작동하지 않음

def constant_factory(value): 
    return itertools.repeat(value).next 

그럼 내가 그것을 사용하려고 :

나는 constant_factory 기능을 구현했습니다. 대신

>>>import itertools 
>>>from collections import defaultdict 
>>>dictio=defaultdict(constant_factory([0,0])) 
>>>for i in xrange(10): 
... dictio[i][0]+=1 
>>>dictio 
defaultdict(<method-wrapper 'next' of itertools.repeat object at 0x000000000355FC50>, {0: [10, 0], 1: [10, 0], 2: [10, 0], 3: [10, 0], 4: [10, 0], 5: [10, 0], 6: [10, 0], 7: [10, 0], 8: [10, 0], 9: [10, 0]}) 

내가 좀하고 싶습니다 : 여기

은 예입니다 defaultdict(<method-wrapper 'next' of itertools.repeat object at 0x000000000355FC50>, {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0], 4: [1, 0], 5: [1, 0], 6: [1, 0], 7: [1, 0], 8: [1, 0], 9: [1, 0]})

내가 기꺼이 때마다 목록의 첫 번째 슬롯의 값을 증가 할 것 같다 키 i에 해당하는 경우 첫 번째 슬롯의 모든 값을 증가시킵니다.

저는 defaultdict와 method wrapper를 사용하는 것에 매우 익숙해 져서 파이썬이 완벽하게 잘 작동한다고 믿는 이래로 제가 잘못하고있는 것을 누군가가 설명 할 수 있습니까? 모든

답변

4

먼저, 그냥 사용

defaultdict(lambda: [0, 0]) 

당신이 아니라 호출 반환 또 다시 동일한 목록 정교한. 귀하의 사전에 모두 값에 대해 동일한 목록을 사용하고 있습니다. 당신은 따라서 목록에 참조하여 사전을 작성하고 하나의 목록에서 값을 변경하는 것은 사방이에 대한 참조를 반영

>>> import itertools 
>>> lambda_default = lambda: [0, 0] 
>>> iter_default = itertools.repeat([0, 0]).next 
>>> lambda_default() is lambda_default() 
False 
>>> iter_default() is iter_default() 
True 

: 위의 람다가 대신 호출 될 때마다 새로운 목록을 반환 하나의 목록이 인쇄됩니다.

+0

모든 것이 분명합니다! 설명서를 읽고 constant_factory 메소드를 찾았지만 어떻게 작동하는지 이해하지 않고 사용했습니다. –