У меня есть файл с сотнями строк JSON в нем.
Нет, вы этого не сделали, и в этом проблема.
Сотни текстов JSON не являются допустимым файлом JSON. Действительный файл JSON - это всего лишь один текст. Вот почему
json.load
возвращает ошибку.Сотни текстов JSON, каждая из которых соответствует только одной строке с символами новой строки между ними , является действительным файлом в другом форматы, такие как JSONlines или NDJ. Он все еще не является допустимым файлом JSON, поэтому вы не можете использовать
json.load
, но вы можете использовать JSONlines или библиотеку NDJ или просто разбирать его следующим образом:with open('fixed.json') as f: for line in f: data = json.loads(line) # do stuff
Для записи файла JSONlines , опять же, вы можете использовать библиотеку JSONlines, или вы можете просто убедиться, что в каждом тексте JSON нет встроенных новых строк, что фактически происходит по умолчанию, если вы не укажете параметры, отличные от параметров по умолчанию
ensure_ascii
илиindent
, и просто напишитеjson.dumps(data) + "\n"
для каждого значения.Но сотни текстов JSON, каждая из которых занимает несколько строк, не является допустимым файлом.
Это на самом деле , объясненный в модуле
json
docs :Примечание. В отличие от
pickle
иmarshal
, JSON не является фрейм-протоколом, поэтому попытка сериализации нескольких объектов с повторением вызовы наdump()
с использованием того же fp приведут к недопустимому файлу JSON.Что означает «не связанный с кадром протокол», это в основном то, что формат будет неоднозначный. Например, если вы сделали
json.dump(2, f)
, а затемjson.dump(3, f)
, то, что вы получили в вашем файле, -23
. Это то же самое, что вы получаете отjson.dump(23, f)
.Если вы можете исправить ваш файл как нечто действительное, например JSONlines, это простое решение.
Если вы не можете ...
Ну, перед стандартизацией была концепция «документа JSON», что означало в основном текст JSON, который является либо массивом, либо объектом. И поток документов JSON not неоднозначен.
Поскольку это не стандартный формат, вы, вероятно, не найдете для него синтаксический анализатор, так что вы будете должен написать один.
Один из способов сделать это - использовать метод
raw_decode
в модулеjson
. Это попытается декодировать текст JSON, возможно, после него, после чего добавит лишний материал, а также вернет индекс для этого дополнительного материала. Что, в вашем случае, является следующим документом JSON.Поскольку сотни объектов такого размера не слишком велики, вероятно, проще просто прочитать весь файл в памяти, а затем проанализировать его, поэтому мы не нужно беспокоиться о буферизации:
with open('fixed.json') as f: contents = f.read() decoder = json.JSONDecoder() while contents: data, idx = decoder.raw_decode(contents) do_stuff(data) contents = contents[idx:].lstrip()
Помните, что это будет работать, только если ваш файл является потоком документов JSON, то есть значения верхнего уровня всегда представляют собой Array или Object. Кроме того, если вы редактируете эти файлы вручную, в отличие от JSONlines, которые могут пропустить один плохой текст и продолжать разбирать остальные, теперь можно восстановить из-за ошибки здесь, потому что вы понятия не имеете, где начинается следующий документ.
Вам нужно сделать два COUNTIF и один COUNTIFS:
=COUNTIF(A:A,"<>")+COUNTIF(B:B,"<>")-COUNTIFS(A:A,"<>",B:B,"<>")
Или вам нужно ограничить диапазон данных, чтобы использовать SUMPRODUCT:
=SUMPRODUCT(--((A1:A1000<>"")+(B1:B1000<>"")>0))