OrderedDict 이해
collections
모듈 의 OrderedDict 또는 상속받은 내 유형 과 같은 다른 사전에 대한 dict 이해를 위해 파이썬에서 구문을 확장 할 수 있습니까 dict
?
dict
이름을 다시 바인딩하는 것은 분명히 작동하지 않습니다. {key: value}
이해 구문은 여전히 이해력과 리터럴에 대한 평범한 오래된 사전을 제공합니다.
>>> from collections import OrderedDict
>>> olddict, dict = dict, OrderedDict
>>> {i: i*i for i in range(3)}.__class__
<type 'dict'>
그래서 가능하다면 어떻게할까요? CPython에서만 작동하면 괜찮습니다. 구문의 O{k: v}
경우 r'various' u'string' b'objects'
.
참고 : 물론 생성기 표현식을 대신 사용할 수 있지만 문법 측면에서 hackable python이 얼마나 있는지 더 관심이 있습니다.
언어 내에서 Python의 구문을 변경하는 직접적인 방법은 없습니다. 사전 이해 (또는 일반 디스플레이)는 항상을 생성하며 이에 dict
대해 할 수있는 작업이 없습니다. CPython을 사용하는 경우 dict를 직접 생성하는 특수 바이트 코드를 사용하여 궁극적으로 PyDict
API 함수 및 / 또는 해당 API에서 사용하는 동일한 기본 함수를 호출합니다 . PyPy를 사용하는 경우 해당 바이트 코드는 대신 dict
컴파일되고 최적화 된 Python 위에 구현되는 RPython 객체 위에 구현됩니다 dict
. 등등.
거기에있다 간접 그것을 할 방법은,하지만 당신은 그것을 좋아하지 않을거야. 가져 오기 시스템 의 문서를 읽으면 캐시 된 컴파일 된 코드를 검색하거나 컴파일러를 호출하는 가져 오기 도구 , 파서를 호출하는 컴파일러 등을 알 수 있습니다. Python 3.3 이상에서는이 체인의 거의 모든 것이 순수 Python으로 작성되거나 대체 순수 Python 구현이 있습니다. 즉, 코드를 포크하고 직접 작업을 수행 할 수 있습니다. 여기에는 AST를 빌드하는 자체 PyParsing 코드로 소스를 구문 분석하거나, dict comprehension AST 노드를 기본값 대신 사용자 지정 바이트 코드로 컴파일하거나, 바이트 코드를 사후 처리하는 것이 포함됩니다.
대부분의 경우 가져 오기 후크 로 충분합니다. 그렇지 않은 경우 언제든지 사용자 정의 파인더 및 로더를 작성할 수 있습니다.
Python 3.3 이상을 아직 사용하고 있지 않다면이 작업을 수행하기 전에 마이그레이션하는 것이 좋습니다. 이전 버전에서는 더 어렵고 잘 문서화되지 않았으며 마이그레이션 할 때마다 쓸모없는 것을 배우기 위해 궁극적으로 10 배의 노력을 기울일 것입니다.
어쨌든이 접근 방식이 흥미로워 보인다면 MacroPy를 살펴 보는 것이 좋습니다 . 여기에서 일부 코드를 빌릴 수 있으며, 더 중요한 것은 이러한 기능 중 일부 (문서에 좋은 예가 없음)가 어떻게 사용되는지 배우는 것입니다.
또는 덜 멋진 것에 만족하고 싶다면 MacroPy
"odict comprehension macro"를 만들고 그것을 사용할 수 있습니다 . (현재 MacroPy는 3.x가 아닌 Python 2.7에서만 작동합니다.)를 얻을 수 o{…}
는 없지만, 예를 들어 얻을 수 od[{…}]
는 있지만 그렇게 나쁘지는 않습니다. 다운로드 od.py
, realmain.py
및 main.py
, 실행 python main.py
은 작업을 볼 수 있습니다. 키가 얻어 코드이다 DictionaryComp
등가로 변환하여, AST를 GeneratorExpr
키 값에 대한 Tuple
S, 및 그것을 감싸는 Call
행 collections.OrderedDict
:
def od(tree, **kw):
pair = ast.Tuple(elts=[tree.key, tree.value])
gx = ast.GeneratorExp(elt=pair, generators=tree.generators)
odict = ast.Attribute(value=ast.Name(id='collections'),
attr='OrderedDict')
call = ast.Call(func=odict, args=[gx], keywords=[])
return call
물론 다른 대안은 Python 인터프리터를 수정하는 것입니다.
나는 O{…}
처음으로 구문 아이디어를 버리고 정상적인 dict 이해를 odict로 컴파일하도록 제안합니다. 좋은 소식은 문법을 변경할 필요가 없다는 것입니다.
- dictcomps가 컴파일되는 바이트 코드,
- 인터프리터가 해당 바이트 코드를 실행하는 방식 또는
PyDict
유형 의 구현
나쁜 소식은 모두 문법을 변경하는 것보다 훨씬 쉽지만 확장 모듈에서 수행 할 수있는 것은 없습니다. (글쎄요, 당신은 기본적으로 순수 파이썬에서했던 것과 같은 일을함으로써 첫 번째를 할 수 있습니다… 그리고 .so / .dll / .dylib를 후킹하여 자신의 함수에서 패치함으로써 그들 중 어느 것이 든 할 수 있습니다. Python 해킹과 똑같은 작업과 런타임에 추가 작업이 추가됩니다.)
당신이 해킹하려는 경우 CPython의 소스 , 당신이 원하는 코드에 Python/compile.c
, Python/ceval.c
그리고 Objects/dictobject.c
, 그리고 dev에 가이드는 어떻게 당신이 필요로하는 모든 것을 찾을 방법을 알려줍니다. 그러나 PyPy 소스 는 대부분 C가 아닌 Python으로 작성 되었기 때문에 대신 PyPy 소스 를 해킹하는 것이 좋습니다.
참고로 모든 것이 Python 언어 수준에서 수행 되었더라도 시도가 작동하지 않았을 것입니다. olddict, dict = dict, OrderedDict
만드는의 이름은 바인딩 dict
모듈의 전역에 그림자 내장 명령에 이름을하지만, 그것을 대체하지 않습니다. 빌트인으로 대체 할 수 있습니다 (파이썬이 이것을 보장하지는 않지만 제가 시도한 모든 구현 / 버전에 대해 작동 할 수있는 구현 / 버전 별 사항이 있습니다…). 그것을하는 방법이 아닙니다.
죄송합니다. Dict 리터럴과 dict 이해는 C 레벨에서 하드 코딩되는 방식으로 내장 dict 유형에 매핑됩니다. 재정의 할 수 없습니다.
그러나 이것을 대안으로 사용할 수 있습니다.
OrderedDict((i, i * i) for i in range(3))
Addendum: as of Python 3.6, all Python dictionaries are ordered. As of 3.7, it's even part of the language spec. If you're using those versions of Python, no need for OrderedDict: the dict comprehension will Just Work (TM).
Slightly modifying the response of @Max Noel, you can use list comprehension instead of a generator to create an OrderedDict in an ordered way (which of course is not possible using dict comprehension).
>>> OrderedDict([(i, i * i) for i in range(5)])
OrderedDict([(0, 0),
(1, 1),
(2, 4),
(3, 9),
(4, 16)])
참고URL : https://stackoverflow.com/questions/21103732/ordereddict-comprehensions
'Program Tip' 카테고리의 다른 글
활성 레코드 마이그레이션 레일의 has_many, belongs_to 관계 4 (0) | 2020.12.07 |
---|---|
Snake 케이스를 Lower Camel Case로 변환 (lowerCamelCase) (0) | 2020.12.07 |
C ++에서 new 대신 std :: allocator를 사용하는 이점은 무엇입니까? (0) | 2020.12.07 |
Jupyter에서 TensorFlow 그래프를 시각화하는 간단한 방법은 무엇입니까? (0) | 2020.12.07 |
PHP 세션 파일 정리 (0) | 2020.12.07 |