#python #json #file #dictionary
Вопрос:
Мне интересно, есть ли какой-либо способ обновить файл json без необходимости полностью переписывать файл json. Как показано в примере ниже, сначала мне пришлось извлечь все данные из файла json, затем добавить/ отредактировать исходные данные, а затем переписать новый словарь данных поверх исходного файла. Можно ли просто отредактировать несколько строк файла json напрямую?
У меня есть основной файл и файл json, которые выглядят следующим образом:
ОСНОВНОЙ ФАЙЛ
import json
with open('animals.json') as f:
data = json.load(f)
attributes = {"Food": "", "Size": "", "Habitat": ""}
data["Animal 1"]["Food"] = "Meat"
data["Animal 1"]["Size"] = "Medium"
data["Animal 1"]["Habitat"] = "Savannah"
attributes["Food"] = "Nuts"
attributes["Size"] = "Small"
attributes["Habitat"] = "Forest"
data["Animal 3"] = dict(attributes)
# attributes["Food"] = "Plankton"
# attributes["Size"] = "Large"
# attributes["Habitat"] = "Ocean"
# data["Animal 2"] = dict(attributes)
with open('animals.json', 'w') as f:
json.dump(data, f, indent=4)
ФАЙЛ JSON
{
"Animal 1": {
"Food": "Banana",
"Size": "Medium",
"Habitat": "Jungle"
},
"Animal 2": {
"Food": "Plankton",
"Size": "Large",
"Habitat": "Ocean"
}
}
В настоящее время код обновляет файл json (атрибуты животного 1 и добавляет Животное 3), чтобы он выглядел следующим образом:
{
"Animal 1": {
"Food": "Meat",
"Size": "Medium",
"Habitat": "Savannah"
},
"Animal 2": {
"Food": "Plankton",
"Size": "Large",
"Habitat": "Ocean"
},
"Animal 3": {
"Food": "Nuts",
"Size": "Small",
"Habitat": "Forest"
}
}
Существуют ли какие-либо альтернативы этому методу?
Комментарии:
1. Если вы хотите сделать это масштабируемым, я бы, вероятно, использовал что-то вроде sqlite, что дало бы вам возможность выбирать конкретные записи и редактировать их.
2. Это не имеет никакого отношения к JSON; файлы так не работают. Кроме того, все это не имеет ничего общего с «загрузкой», что означает передачу вашего файла с вашего компьютера на сервер.
3. Поэтому я не могу использовать его с файлами json @dir
4. @ChristopherOjo Я понятия не имею, каковы ваши долгосрочные цели, но чтобы ответить на этот вопрос: нет. Вам придется каждый раз переписывать файл заново.
5. «вся проблема в «загрузке» в «файл json» «» Нет, это не так. Слово «загрузка» означает не то, что вы, по-видимому, думаете, что оно означает .
Ответ №1:
Я предполагаю, что вы увеличите масштаб процесса с гораздо большим количеством данных, поэтому перезапись данных json можно легко выполнить с помощью фреймов данных pandas. Главное здесь то, что вам не нужно беспокоиться о том, что каждое поле json будет обновляться, как вы показали в своем коде. Я не буду заниматься сохранением/записью файлов, так как это не проблема. Если бы не информация о json, при таком подходе решение занимало бы всего 6 строк кода. Пошаговое объяснение я показываю после полного кода.
Кстати, вы также можете читать из файла json напрямую, используя pd.read_json('file_name.json')
и записывая в него datraframe_object.to_json('file_name.json')
.
Полный код для тех, кто хочет воспроизвести:
import json
import pandas as pd
original_json = {
"Animal 1": {
"Food": "Banana",
"Size": "Medium",
"Habitat": "Jungle"
},
"Animal 2": {
"Food": "Plankton",
"Size": "Large",
"Habitat": "Ocean"
}
}
overwrite_json = {
"Animal 1": {
"Food": "Meat",
"Size": "Medium",
"Habitat": "Savannah"
},
"Animal 2": {
"Food": "Plankton",
"Size": "Large",
"Habitat": "Ocean"
},
"Animal 3": {
"Food": "Nuts",
"Size": "Small",
"Habitat": "Forest"
}
}
#here the six lines to get your updated json info
original_frame = pd.DataFrame(original_json).T
overwrite_frame = pd.DataFrame(overwrite_json).T
original_frame['index'] = original_frame.index
overwrite_frame['index'] = overwrite_frame.index
updated_frame = original_frame.merge(overwrite_frame,how='right').set_index('index')
final_json = updated_frame.to_json(orient='index',indent=4)
print(final_json)
Вывод:
{
"Animal 1":{
"Food":"Meat",
"Size":"Medium",
"Habitat":"Savannah"
},
"Animal 2":{
"Food":"Plankton",
"Size":"Large",
"Habitat":"Ocean"
},
"Animal 3":{
"Food":"Nuts",
"Size":"Small",
"Habitat":"Forest"
}
}
Пошаговое объяснение:
- Импортируйте панду, которая обычно используется для обработки данных, поэтому она хорошо документирована и используется многими.
import json
import pandas as pd
- Здесь я предполагаю, что вы сделаете свою вещь с открытым файлом. Для простоты я просто назначу объекты json с предоставленной вами информацией.
original_json = {
"Animal 1": {
"Food": "Banana",
"Size": "Medium",
"Habitat": "Jungle"
},
"Animal 2": {
"Food": "Plankton",
"Size": "Large",
"Habitat": "Ocean"
}
}
overwrite_json = {
"Animal 1": {
"Food": "Meat",
"Size": "Medium",
"Habitat": "Savannah"
},
"Animal 2": {
"Food": "Plankton",
"Size": "Large",
"Habitat": "Ocean"
},
"Animal 3": {
"Food": "Nuts",
"Size": "Small",
"Habitat": "Forest"
}
}
- Создайте фреймы данных pandas из информации json. Я перенес (
.T
) сюда, чтобы сохранить вашу первоначальную ориентацию на записи json.
original_frame = pd.DataFrame(original_json).T
overwrite_frame = pd.DataFrame(overwrite_json).T
Кадры данных выглядят так. Они проиндексированы на «Животное 1», «Животное 2» и так далее:
print(original_frame)
Food Size Habitat
Animal 1 Banana Medium Jungle
Animal 2 Plankton Large Ocean
print(overwrite_frame)
Food Size Habitat
Animal 1 Meat Medium Savannah
Animal 2 Plankton Large Ocean
Animal 3 Nuts Small Forest
- Сохраните индексы каждого фрейма данных в новом столбце для последующего использования.
original_frame['index'] = original_frame.index
overwrite_frame['index'] = overwrite_frame.index
#example of 'index' column created
print(original_frame)
Food Size Habitat index
Animal 1 Banana Medium Jungle Animal 1
Animal 2 Plankton Large Ocean Animal 2
- Затем мы объединяем два кадра данных, перезаписывая исходный кадр с кадром перезаписи. Смотрите, что я использую
how='right'
, чтобы отдать предпочтениеoverwrite_frame
иset_index
использовать ранее сохраненные столбцы индекса.
updated_frame = original_frame.merge(overwrite_frame,how='right').set_index('index')
print(update_frame)
Food Size Habitat
index
Animal 1 Meat Medium Savannah
Animal 2 Plankton Large Ocean
Animal 3 Nuts Small Forest
- Затем просто сгенерируйте новый json из полученного фрейма данных
final_json = updated_frame.to_json(orient='index',indent=4)
print(final_json)
{
"Animal 1":{
"Food":"Meat",
"Size":"Medium",
"Habitat":"Savannah"
},
"Animal 2":{
"Food":"Plankton",
"Size":"Large",
"Habitat":"Ocean"
},
"Animal 3":{
"Food":"Nuts",
"Size":"Small",
"Habitat":"Forest"
}
}
Если я правильно понял ваш вопрос, это решит ваше узкое место!