2016-11-05 2 views
3
내가 파이썬 새로운 현재 파이썬 2 내가 다음과 같습니다 다차원 사전을 내장 사용하고

:인쇄 다차원 사전

targets = {house: {N: {red: {A:1}, garden: {N: 6}}} 
      {great: {A: {very: {Adv:12}, so: {Adv: 5}, a: {Det: 3}}}} 
etc. 

기본적으로 항상 4 중첩 된 사전 만의 항목이있다 '세 번째'사전 ({red : {}, horse : {} 등)은 임의의 수의 항목으로 구성 될 수 있습니다. 따라서 사전에있는 항목의 수는 다양합니다.

이제는 사전을 파일로 작성하고 싶습니다. CSV 파일로 작성하는 것이 좋습니다. 출력 파일은 탭으로 구분 된 방식으로 모든 항목을 표시해야하며, 각 행은 가장 먼 키부터 시작해야합니다. 예를 들어 :

내가 아는
house N red  A 1 
house N garden N 6 
great A very  Adv 12 
great A so  Adv 5 
great A a  Det 3 

은 다차원 사전 인쇄에 대한 글을 많이하지만 내가 발견하지 않은, 거기에 최 키마다 반복하는 동안 인쇄 한 (아직). 다차원 사전에 관한 다른 질문에 제공된 코드 스 니펫을 포함 시키려고했지만 지금까지 제대로 작동하지 않았습니다. 또한이 (내가 아는

for target in targets_dict: 
    results.write(str(target) + str(targets_dict[str(target)]) + '\n') 

또는 csvwriter을 사용하여 CSV 파일에 기록 :

난 그냥 루프이와 사전 형식의 정상이 .txt 파일로 사전을 작성하는 관리 DictWriter, 나는 그냥)가 제대로 동작하지 않습니다 수 :

w = csv.writer(results, delimiter = '\t') 
for target in targets_dict.iteritems(): 
    w.writerow(target) 

은 분명히, 이것은 매우 기초적인 수준이고 반복 내부 사전을 입력하지 않습니다.

관련 문제에 게시 된 수정 된 솔루션을 시도하는 중 (recursively traverse multidimensional dictionary, dimension unknown)은 항상 '예상되는 문자 버퍼 개체'오류에 있습니다.

for for k,v in sorted(targets_dict.items(),key=lambda x: x[0]): 
    if isinstance(v, dict): 
     results.write(" ") + ("%s %s") % (k, v) 

모든 제안이나 힌트는이 모든 것의 배후에있는 논리를 이해하도록 도와 주므로 감사하겠습니다.

+1

Re. 변수'targets' : 이것은 dicts의 목록입니까, 아니면 가장 바깥에있는 사전의 모든 키입니까? – Eugene

+0

가장 가까운 사전의 모든 키는 고유 한 –

답변

1

다음은 간단한 해결책입니다. 생각은 dict을 반복하여 목록에 넣은 다음 해당 목록에서 tsv 파일을 만드는 것입니다. 단, 네스트 깊이 (4, 괜찮은 것 같습니다)를 알고 있어야합니다. 아래는 속도에 최적화되어 있지 않으며 어디서나 존재 여부를 확인하지는 않지만 잘하면 아이디어를 얻을 수 있습니다.

import csv 
targets = {'house': {'N': {'red': {'A':1}, 'garden': {'N': 6}}}, 
      'great': {'A': {'very': {'Adv':12}, 'so': {'Adv': 5}, 'a': {'Det': 3}}}} 
with open('targets.tsv', 'w', newline='\n') as tsvfile: 
    writer = csv.writer(tsvfile, delimiter='\t') 
    for t in targets: 
     for u in targets[t]: 
      for v in targets[t][u]: 
       for w in targets[t][u][v]: 
        #print [t, u, v, w, targets[t][u][v][w]] 
        writer.writerow([t, u, v, w, targets[t][u][v][w]]) 

인쇄 : 또한

['house', 'N', 'red', 'A', 1] 
['house', 'N', 'garden', 'N', 6] 
['great', 'A', 'very', 'Adv', 12] 
['great', 'A', 'so', 'Adv', 5] 
['great', 'A', 'a', 'Det', 3] 

그리고는 TSV 파일 생성 :

house N red A 1 
house N garden N 6 
great A very Adv 12 
great A so Adv 5 
great A a Det 3 

편집을 : 가장 바깥 쪽 사전에 키가 고유 (OP에 언급을 따라 업데이트 코드 targets의 키로 취급되어야합니다.

+1

와우입니다. 늦어서 답변 해 주셔서 감사 드리며 죄송합니다. 위의 설명에서 말했듯이 타겟은 가장 바깥에있는 사전입니다. 그러나 코드에 대한 아이디어를 얻을 수 있으며 전반적인 논리를 이해하는 데 도움이됩니다. –

+0

답장을 보내고 답변을 선택해 주셔서 감사합니다. 많은 신규 사용자는 그렇지 않으며, SO에서 시작하는 사람들을 도울 수있는 의지를 복원하는 사람과 같은 사람들입니다! 다시 한 번 감사드립니다! – Eugene

+0

완료를위한 주석을 반영하도록 코드를 업데이트했습니다. – Eugene

1

실제로 재귀가 문제의 해결책입니다. 발견 된 항목의 경로를 생성하는 동안 사전을 반복적으로 가로 지르는 생성자 함수를 정의 할 수 있습니다.당신은 비 DICT 항목을 발생하면 바로 yield 경로에 추가 CSV 파일에 그 쓰기 된 어떤 :

import csv 

targets = { 
    'house': {'N': {'red': {'A':1}, 'garden': {'N': 6}}}, 
    'great': {'A': {'very': {'Adv':12}, 'so': {'Adv': 5}, 'a': {'Det': 3}}} 
} 

def get_rows(o, path=None): 
    if path is None: 
     path = [] 

    # Base case, add object to path and yield it 
    if not isinstance(o, dict): 
     path.append(o) 
     yield path 
     path.pop() 
     return 

    for k, v in o.items(): 
     path.append(k) 
     yield from get_rows(v, path) 
     path.pop() 

with open('result.csv', 'w', newline='') as f: 
    writer = csv.writer(f, delimiter='\t') 
    for row in get_rows(targets): 
     writer.writerow(row) 

출력 : 당신이 얻을 출력이 다른 순서로 될 수 있음을

great A a Det 3 
great A so Adv 5 
great A very Adv 12 
house N red A 1 
house N garden N 6 

dict은 정렬되지 않았기 때문에. 위의 솔루션은 깊이가있는 중첩 된 사전을 사용합니다. 파이썬 2를 사용한다면, 파이썬 2에는 yield from이 없으므로 약간 수정해야합니다.

+0

OP는 "출력 파일은 탭으로 구분 된 방식으로 모든 항목을 표시해야합니다"라고 말하면 위의 코드에서 탭 구분 기호를 설정해야합니다. – Eugene

+0

@Eugene 좋은 점, 그것을 고쳤습니다. – niemmi

+0

@niemmi 정말 고마워,이 프로젝트를 위해 Python 2를 사용하고 있지만 파이썬 3을 사용해 보았고 원하는 출력을 제공한다.) –

1

그것은 모든 dicts을 통해 루프 단지 둥지 매우 간단하다 :

import csv 

targets = {'house': {'N': {'red': {'A':1}, 'garden': {'N': 6}}}, 'great': {'A': {'very': {'Adv':12}, 'so': {'Adv': 5}, 'a': {'Det': 3}}}} 

with open('file.csv', 'wb') as csvfile: 
    csvwriter = csv.writer(csvfile, delimiter='\t') 
    for k,v in targets.iteritems(): 
    for k2,v2 in v.iteritems(): 
     for k3,v3 in v2.iteritems(): 
     for k4,v4 in v3.iteritems(): 
      csvwriter.writerow([str(k), str(k2), str(k3), str(k4), str(v4)]) 
      #print(str(k) + "\t" + str(k2) + "\t" + str(k3) + "\t" + str(k4) + "\t" + str(v4)) 

출력은 당신이 원하는 정확히.

+0

정말 도움을 주셔서 감사합니다. 내가 뭘 찾고 있었는지. 당신의 공헌에 정말로 감사 드리며, 많은 도움이되었습니다! –