2014-04-06 2 views
1

파일 내보내기 그래서 나는 CSV는 다음과 같이 배열 된 데이터 파일이 있습니다가져 오기/A CSV에서 중첩 된 사전

X,a,1,b,2,c,3 
Y,a,1,b,2,c,3,d,4 
Z,l,2,m,3 

내가 그 다음과 같습니다 있도록 중첩 된 사전을 만들기 위해 CSV를 가져올.

data = {'X' : {'a' : 1, 'b' : 2, 'c' : 3}, 
     'y' : {'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4}, 
     'Z' : {'l' : 2, 'm' :3}} 

내가 쓴 프로그램에서 사전을 업데이트 한 후이를 업데이트/덮어 쓰기, 내가 같은 CSV 파일에 사전을 수출 할 수있게하려면 (그 부분은 파악 있어요). 그러나 이전 CSV 파일과 동일한 형식으로되어 있으므로 다시 가져올 수 있습니다.

는 내가 가져 오기 장난이 지금까지

import csv 
data = {} 
with open('userdata.csv', 'r') as f:  
    reader = csv.reader(f) 
    for row in reader: 
     data[row[0]] = {row[i] for i in range(1, len(row))} 

이 지금은 상황이 제대로 배치되지 않는 한이 작동하지 않습니다되었다. 어떤 숫자는 다른 숫자의 하위 키이고, 글자는 틀립니다. 나는 아직 수출 부분에 이르지 않았습니다. 어떤 아이디어?

+0

dicts는 주문하지 않습니다. '데이터'에 주문 정보가 필요한 경우 OrderedDict와 같은 다른 구조를 사용해야합니다. – BrenBarn

+0

미안하지만 정렬 된 것을 의미하지는 않습니다. 데이터 에서처럼 내가 제시 한 사전처럼 정렬되지 않습니다. 어떤 숫자는 다른 숫자의 키입니다. 나는 그것을 명확하게하기 위해 편집했습니다. – nothisispatrick11

+0

질문을 명확히해야합니다. 대표적인 입력 샘플과 예상 출력을 추가하십시오. –

답변

1

당신이 관심이없는 것 때문에 순서를 보존하기에 비교적 간단 뭔가 작업을해야합니다 :

import csv 

# import 
data = {} 
with open('userdata.csv', 'r') as f: 
    reader = csv.reader(f) 
    for row in reader: 
     a = iter(row[1:]) 
     data[row[0]] = dict(zip(a, a)) 

# export 
with open('userdata_exported.csv', 'w') as f: 
    writer = csv.writer(f) 
    for key, values in data.items(): 
     row = [key] + [value for item in values.items() for value in item] 
     writer.writerow(row) 

csv.writer의에 단 하나의 호출하여보다 효율적으로 조금 할 수 후자메서드를 호출하고 generator expression을 전달합니다.

# export2 
with open('userdata_exported.csv', 'w') as f: 
    writer = csv.writer(f) 
    rows = ([key] + [value for item in values.items() for value in item] 
      for key, values in data.items()) 
    writer.writerows(rows) 
+0

이것은 완벽하게 작동했습니다. 나는 내가 잘못 가고있는 곳을 본다. 감사! – nothisispatrick11

0

당신은 itertools에서 grouper 조리법을 사용할 수 있습니다

def grouper(iterable, n, fillvalue=None): 
    "Collect data into fixed-length chunks or blocks" 
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx 
    args = [iter(iterable)] * n 
    return itertools.izip_longest(fillvalue=fillvalue, *args) 

이 의지 그룹 데이터를 원하는 A1/B2/C3 쌍으로. 따라서 루프에서 data[row[0]] = {k: v for k, v in grouper(row[1:], 2)}을 수행 할 수 있습니다.

0
from collections import defaultdict 

data_lines = """X,a,1,b,2,c,3 
Y,a,1,b,2,c,3,d,4 
Z,l,2,m,3""".splitlines() 

data = defaultdict(dict) 

for line in data_lines: 
# you should probably add guards against invalid data, empty lines etc. 
    main_key, sep, tail = line.partition(',') 
    items = [item.strip() for item in tail.split(',')] 
    items = zip(items[::2], map(int, items[1::2]) 
    # data[main_key] = {key : value for key, value in items} 
    data[main_key] = dict(items) 

print dict(data) 
# {'Y': {'a': '1', 'c': '3', 'b': '2', 'd': '4'}, 
# 'X': {'a': '1', 'c': '3', 'b': '2'}, 
# 'Z': {'m': '3', 'l': '2'} 
# } 
0

나는 게으른, 그래서 나는 이런 식으로 뭔가 할 수 있습니다

row[1::2] 1에서 시작하는 다른 모든 요소를 ​​제공하기 때문에 작동
import csv 
data = {} 

with open('userdata.csv', 'rb') as f:  
    reader = csv.reader(f) 
    for row in reader: 
     data[row[0]] = dict(zip(row[1::2], map(int,row[2::2]))) 

row[2::2 다른 모든 요소가 2 zip 차종에서 시작을 그 두 요소의 튜플 쌍을 만든 다음 dict에 전달합니다. 이

{'Y': {'a': 1, 'c': 3, 'b': 2, 'd': 4}, 
'X': {'a': 1, 'c': 3, 'b': 2}, 
'Z': {'m': 3, 'l': 2}} 

(나는 당신의 open 파이썬 2에 적합한 'rb', 사용하도록 변경합니다. : 당신이 3를 사용하는 경우, 대신 'r', newline=''을 원하는)를 제공