2017-02-19 2 views
2

Я пытаюсь добавить пару ключевых значений из одного dict в другой. Это звучит довольно просто, но сложность диктонов сильно отличается. Для контекста я построил два dicts, проанализировав два файла данных, используя модули python json и csv. json dict сложный, имеющий несколько уровней, в то время как мой tsv dict - это простой ключ ключей: значение. Позвольте мне порезать каждый с индексом 1, чтобы проиллюстрировать это:Iterative Dict Merging Issue

json_data['objects']['counties']['geometries'][1] 
>> {'arcs':[[4,5,6,7,8,9]], 'id':30105, 'type': 'Polygon'} 

Ну, я предполагаю, что я не могу нарезать TSV Dict на 1, но пример слайс:

tsv_data[30105] 
>>'Valley' 

Примечание мой TSV ключи - целые числа, а индексирование двух dicts различно, на самом деле len(tsv_data) != len(json_data[et all]). Но это нормально. Моя цель состоит в том, чтобы объединить их таким образом, чтобы я добавить свойство имени в качестве ключевого значения пары в файл JSON, как это:

json_data['objects']['counties']['geometries'][1] 
>> {'arcs':[[4,5,6,7,8,9]], 'id':30105, 'type': 'Polygon', 'name':'Valley'} 

Я скопировал один кусочек для тестирования воды:

json_data_subset = copy.copy(json_data['objects']['counties']['geometries'][1]) 
json_data_subset['name'] = tsv_data[json_data_subset['id']] 
>> {'arcs':[[4,5,6,7,8,9]], 'id':30105, 'type': 'Polygon', 'name':'Valley'} 

Итак, как вы можете видеть, в этом случае это сработало. Так я думал, что я на правильном пути, и продолжил перебирать:

j = json_data['objects']['counties']['geometries'] 
for i in j: 
    j[i]['name'] = tsv_data[j[i]['id']] 

Но это дало мне:

TypeError: list indices must be integers or slices, not dict.

Тем не менее он работал в вышеописанном случае, я не знаю, почему он изменил его мелодию.

Что я могу сделать для повторения и слияния диктонов, как это было сделано в случае с одним срезом?

Для ясности, что я пытаюсь сделать, это с этим для петли найти соответствующий номер документа в файле tsv, используя id ключ файла json. Из этого я могу получить совпадающее имя из tsv, которое затем я хочу подключить к файлу json как 'name':'Name of Value'. Я уверен, что это один из лучших способов сделать это, учитывая, что у меня нет последовательных или совпадающих заказов между диктофонами. Если я ошибаюсь, не стесняйтесь предлагать лучший способ.

Edit:

Для целей рассмотрения моего дела точно, я представлю свой код для создания dicts и ссылки на json и tsv. Таким образом, вы можете просто скопировать и вставить, чтобы точно увидеть, что происходит под капотом.

import json 
with open('us.json') as f: 
    json_data = json.load(f) 

import csv 
with open('us-county-names.tsv') as f: 
    tsv_obj = csv.reader(f, delimiter='\t') 
    tsv_data = {int(rows[0]):rows[1] for rows in tsv_obj} 

link в JSON и TSV (немного большой, но не избыточно)

+0

Вы не показываете данные, поэтому я не могу точно сказать, что происходит. Вы должны создать пример [Минимальный, Полный и Подтверждаемый] (http://stackoverflow.com/help/mcve).Это облегчает нам помощь. –

+0

Хорошо, я предоставил соответствующие строки кода и полный набор данных для обеспечения надежности. Его можно отбирать, если нужно, я полагаю. –

+0

Ну, этот пример не был минимальным, но, по крайней мере, он был полным. –

ответ

1

Проблемы вашего облицовочный связано с тем, что j не является dict, это list. Вам нужно что-то еще:

j = json_data['objects']['counties']['geometries'] 
for i in j: 
    name = tsv_data.get(i['id']) 
    if name is None: 
     print('id %d not found' % i['id']) 
    else: 
     i['name'] = tsv_data[i['id']] 
+0

О, это объясняет. Думаю, когда я взял кусочек данных, это был дикт. Но, чтобы сделать это через весь json, это не диктат dicts, это список dicts. Спасибо, что посмотрели на это и показали мне лучший способ. Вероятно, это никогда не осветил бы меня. –

+1

@ArashHowaida, пожалуйста. Вот почему мы рекомендуем вам создавать MCVE. Если вы потратили время на то, чтобы сократить набор данных до размерного размера, вы, вероятно, заметили бы тот факт, что это список, и решили бы свою проблему, просто пытаясь собрать MCVE для совместного использования. Но даже если вы не заметите. Проводя это MCVE, вы получите более быстрые ответы. Приветствия. –

+0

Одна дополнительная зависание, с которой я столкнулся, была в строке 'name =' line. Это говорит, что 'i ['id']' является int, а не iterable. Хотя иногда это нормально. Например, я получил диагностическую строку: id 8014 не найден. Произошла ли ошибка int с вами? –