Python: скрытие значений пустых ключей json в операторе печати
Это моя первая программа на Python, получающая данные через файлы json для создания научных ссылок:
....
js = json.loads(data)
# here is an excerpt of my code:
print("Journal articles:")
for art in js['response']['docs']:
stuff = art['docType_s']
if not stuff == 'ART': continue
tit = art['title_s'][0]
nom = art['authFullName_s'][0]
jou = art['journalTitle_s']
dat = art['producedDateY_i']
try:
pbm = art['pubmedId_s']
except (KeyError, NameError):
pbm = ""
print(nom,', ', tit, '. ', jou, '.', dat, '. Pubmed: ', pbm, sep="")
# sample output: J A. Anderson, Looking at the DNA structure, Nature, 2018. Pubmed: 3256988
Пока он работает нормально, за исключением того, что я не знаю, как скрыть значения ключей из оператора print, когда ключи не имеют значения (т. Е. В файле json такого ключа нет для одной конкретной цитаты).
Например, некоторые из научных ссылок не имеют идентификатора ключа / значения "Pubmed" (pmd). Вместо того, чтобы печатать "Pubmed: " с пустым значением, я хотел бы избавиться от них обоих:
# Desired output (when pbm key is missing from the JSON file):
# J A. Anderson, Looking at the DNA structure, Nature, 2018.
# NOT: J A. Anderson, Looking at the DNA structure, Nature, 2018. Pubmed:
Я попробовал следующее (не печатать pmd, если значение пусто), но это не работает:
print('. Pubmed: ', pbm if pbm != "")
Спасибо за вашу помощь.
3 ответа
Вы можете сделать следующее:
js = json.loads(data)
print("Journal articles:")
for art in js['response']['docs']:
stuff = art['docType_s']
if not stuff == 'ART': continue
tit = art.get('title_s', None)[0]
nom = art.get('authFullName_s', None)[0]
jou = art.get('journalTitle_s', None)
dat = art.get('producedDateY_i', None)
pbm = art.get('pubmedId_s', None)
l = []
for e in (tit, nom, jou, dat, pbm):
if e:
if e is pbm:
l.append('Pubmed: ' + str(e))
else:
l.append(str(e))
pub = ', '.join(l).strip(', ')
print(pub)
Используемая здесь магия находится внутри get
функция, которую нам предоставляет объект dict. Таким образом, вы можете определить значение по умолчанию в случае, если в вашем dict отсутствует определенный ключ (ваш объект JSON - это не что иное, как dict в Python). При использовании этого вы можете избежать написания большого количества if
и до сих пор есть несколько расширяемый и безопасный метод для создания вашей строки. Кроме того, вы не запрашиваете свой диктат дважды, как описано здесь.
Если ваш результат JSON будет содержать больше полей в будущем, вам просто нужно добавить их в этот набор здесь
...
for e in (tit, nom, jou, dat, pbm): #<-- insert more values here
...
и они будут добавлены к строке в порядке их перечисления.
Подробнее о встроенных функциях dict смотрите здесь.
Вы сделали почти правильно! за исключением встроенного, если заявления должны иметь условие else,
изменить этоprint(nom,', ', tit, '. ', jou, '.', dat, '. Pubmed: ', pbm, sep="")
в print(nom,', ', tit, '. ', jou, '.', dat, '. Pubmed: ' if len(pbm)!=0 else "", pbm if len(pbm)!=0 else "", sep="")
Поэтому, если нет ключа Pubmed, pbm будет "", а len(pbm) равно 0.(Вы также можете использовать pbm=""). В этих случаях " Pubmed: 'value' " не будет напечатано.
Я думаю, что лучший / самый чистый способ будет использовать "длинный" if/else
:
if pbm:
print(nom,', ', tit, '. ', jou, '.', dat, '. Pubmed: ', pbm, sep="")
else:
print(nom,', ', tit, '. ', jou, '.', dat, ', sep="")
Вы можете сделать это немного чище, используя строку формата:
if pbm:
print("%s, %s, %s. %s Pubmed: %s" % (nom, tit, jou, dat, pbm))
else:
print("%s, %s, %s. %s" % (nom, tit, jou, dat))
Или объедините строку формата с троичной ... if ... else ...
:
print("%s, %s, %s. %s%s" % (nom, tit, jou, dat, ((" Pubmed: " + pbm) if pbm else "")))
Лично я бы пошел со вторым вариантом.