[PYTHON] 이 함수는 어떻게 OrderedDict를 구현하기 위해 재 작성 될 수 있습니까?
PYTHON이 함수는 어떻게 OrderedDict를 구현하기 위해 재 작성 될 수 있습니까?
사전에 XML 파일을 파싱하는 작업을 수행하는 다음과 같은 기능이 있습니다.
불행히도 파이썬 사전은 순서가 지정되지 않았으므로 노드를 순환 할 수 없습니다.
이를 어떻게 변경하여 'for'로 반복 할 때 노드의 원래 순서를 반영하는 정렬 된 사전을 출력합니다.
def simplexml_load_file(file):
import collections
from lxml import etree
tree = etree.parse(file)
root = tree.getroot()
def xml_to_item(el):
item = None
if el.text:
item = el.text
child_dicts = collections.defaultdict(list)
for child in el.getchildren():
child_dicts[child.tag].append(xml_to_item(child))
return dict(child_dicts) or item
def xml_to_dict(el):
return {el.tag: xml_to_item(el)}
return xml_to_dict(root)
x = simplexml_load_file('routines/test.xml')
print x
for y in x['root']:
print y
출력 :
{'root': {
'a': ['1'],
'aa': [{'b': [{'c': ['2']}, '2']}],
'aaaa': [{'bb': ['4']}],
'aaa': ['3'],
'aaaaa': ['5']
}}
a
aa
aaaa
aaa
aaaaa
collections.OrderedDict를 구현하면 노드의 올바른 순서를 얻을 수 있습니다.
참조 용 XML 파일 :
<root>
<a>1</a>
<aa>
<b>
<c>2</c>
</b>
<b>2</b>
</aa>
<aaa>3</aaa>
<aaaa>
<bb>4</bb>
</aaaa>
<aaaaa>5</aaaaa>
</root>
해결법
-
==============================
1.버전 2.7 *의 표준 라이브러리 콜렉션 모듈에 추가 된 새로운 OrderedDict dict 하위 클래스를 사용할 수 있습니다. 실제로 필요한 것은 Ordered + defaultdict 조합입니다.하지만 아래에 나와있는 것처럼 OrderedDict를 서브 클래 싱하여 생성 할 수 있습니다 :
버전 2.7 *의 표준 라이브러리 콜렉션 모듈에 추가 된 새로운 OrderedDict dict 하위 클래스를 사용할 수 있습니다. 실제로 필요한 것은 Ordered + defaultdict 조합입니다.하지만 아래에 나와있는 것처럼 OrderedDict를 서브 클래 싱하여 생성 할 수 있습니다 :
import collections class OrderedDefaultdict(collections.OrderedDict): """ A defaultdict with OrderedDict as its base class. """ def __init__(self, default_factory=None, *args, **kwargs): if not (default_factory is None or isinstance(default_factory, collections.Callable)): raise TypeError('first argument must be callable or None') super(OrderedDefaultdict, self).__init__(*args, **kwargs) self.default_factory = default_factory # called by __missing__() def __missing__(self, key): if self.default_factory is None: raise KeyError(key,) self[key] = value = self.default_factory() return value def __reduce__(self): # optional, for pickle support args = (self.default_factory,) if self.default_factory else tuple() return self.__class__, args, None, None, self.iteritems() def __repr__(self): # optional return '%s(%r, %r)' % (self.__class__.__name__, self.default_factory, list(self.iteritems())) def simplexml_load_file(file): from lxml import etree tree = etree.parse(file) root = tree.getroot() def xml_to_item(el): item = el.text or None child_dicts = OrderedDefaultdict(list) for child in el.getchildren(): child_dicts[child.tag].append(xml_to_item(child)) return collections.OrderedDict(child_dicts) or item def xml_to_dict(el): return {el.tag: xml_to_item(el)} return xml_to_dict(root) x = simplexml_load_file('routines/test.xml') print(x) for y in x['root']: print(y)
테스트 XML 파일에서 생성 된 출력은 다음과 같습니다.
산출:
{'root': OrderedDict( [('a', ['1']), ('aa', [OrderedDict([('b', [OrderedDict([('c', ['2'])]), '2'])])]), ('aaa', ['3']), ('aaaa', [OrderedDict([('bb', ['4'])])]), ('aaaaa', ['5']) ] ) } a aa aaa aaaa aaaaa
나는 당신이 원하는 것에 가깝다고 생각합니다.
* Python 버전에 v2.5에서 소개 된 OrderedDict가없는 경우 Raymond Hettinger의 Py2.4 ActiveState 레서피 용 Ordered Dictionary를 기본 클래스로 사용할 수 있습니다.
부 업데이트 :
__reduce __ () 메소드를 추가하여 클래스의 인스턴스를 pickle 및 unpickle되도록합니다. 이것은이 질문에 필요하지는 않았지만 비슷한 질문에 나타났습니다.
-
==============================
2.여기에 답변에 나열된 OrderedDict의 구현은 여러 가지가 있습니다. 삽입 된 순서대로 사전에서 항목을 어떻게 검색합니까?
여기에 답변에 나열된 OrderedDict의 구현은 여러 가지가 있습니다. 삽입 된 순서대로 사전에서 항목을 어떻게 검색합니까?
구현 중 하나를 복사하여 자신의 코드에서 사용할 OrderedDict 모듈을 직접 만들 수 있습니다. 실행중인 Python 버전 때문에 OrderedDict에 액세스 할 수 없다고 가정합니다.
귀하의 질문 중 하나 흥미로운 측면은 defaultdict 기능에 대한 필요성입니다. 이를 원하면 __missing__ 메소드를 구현하여 원하는 효과를 얻을 수 있습니다.
-
==============================
3.martineau의 요리법이 저에게는 효과적이지만 DefaultDict에서 상속 된 copy () 메소드에 문제가 있습니다. 다음과 같은 접근 방식은이 단점을 수정합니다.
martineau의 요리법이 저에게는 효과적이지만 DefaultDict에서 상속 된 copy () 메소드에 문제가 있습니다. 다음과 같은 접근 방식은이 단점을 수정합니다.
class OrderedDefaultDict(OrderedDict): #Implementation as suggested by martineau def copy(self): return type(self)(self.default_factory, self)
이 구현은 deepcopy를 수행하지 않는다는 것을 고려하십시오. 이는 대부분의 상황에서 기본 딕셔너리가 아닌 옳은 일로 보이는 것입니다
from https://stackoverflow.com/questions/4126348/how-can-this-function-be-rewritten-to-implement-ordereddict by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 값 사이에 공백없이 변수를 인쇄하는 법 [duplicate] (0) | 2018.10.05 |
---|---|
[PYTHON] python matplotlib 함수에서 산점도 업데이트 (0) | 2018.10.05 |
[PYTHON] 메소드가 참조 평등을 갖는 이유는 무엇입니까? (0) | 2018.10.05 |
[PYTHON] Windows에서 실행되는 PyQt 앱에서 콘솔 창을 숨기려면 어떻게해야합니까? (0) | 2018.10.05 |
[PYTHON] 파이썬에서 백 슬래시 사용하기 (탈출하지 않기) (0) | 2018.10.05 |