Мой ответ JSON имеет следующую структуру:
{
"hpsId": 10012,
"powerPlant": {
"name": "xx",
"id": xx,
"spotlessId": xx,
"regionId": xx,
"priceArea": x,
"timeSeries": [
{
"name": "ts.plan.sum",
"dtssId": "",
"tsv": {
"pfx": false,
"data": [
[
1724846400,
83
],
{
"name": "ts.max_prod.sum",
"dtssId": "",
"tsv": {
"pfx": false,
"data": [
[
1724846400,
null
],
....
Я хочу проверить, не является ли элемент данных FIRST нулевым (теперь он равен 83), и я хочу вернуть его, т. е. 1 из него не равен нулю, а 0, если он равен нулю, используя примерно такой метод (псевдокод):
def get_bids_for_pp(d):
for x in d
for unit in x["data[0]"]:
if unit["data[0[1]]"] !=None
return 1
else:
return 0
Я понимаю, что мне нужно использовать None (не null) для Python, но правильна ли логика метода?
да, я хочу проверить второй элемент (83)
«Правильна ли логика в методе?» - Ты пробовал? Это сработало?
Вам действительно нужно проверить None
? Если список содержит только 1 элемент, вы можете проверить длину: return len(myData['timeSeries'][0]['tsv']['data']) > 1
В списке есть элементы со значением null (ответ json)
Ваш JSON неверен. Если data
— это список списков, у вас должно быть две закрывающие скобки, и у вас есть одна.
Например, вы можете проверить, не является ли второй элемент нулевым для всех данных внутри массива «данных» внутри «tsv» для всех «временных рядов».
return all(unit[1] is not None for ts in d["timeSeries"] for unit in ts["tsv"]["data"])
Используя ваш пример @KamilCuk, я получаю подчеркивание: «Сравнение с None выполняется с помощью операторов равенства»
Это должно быть is not None
, а не != None
.
Вот функция Python, которая проверяет, не является ли первый элемент данных в ответе JSON None, и возвращает 1 или 0 соответственно:
def get_bids_for_pp(d):
for ts in d.get("powerPlant", {}).get("timeSeries", []):
# Check the 'data' key in the 'tsv' dictionary
data = ts.get("tsv", {}).get("data", [])
if data:
# Check if the first element in the data list is not None
first_entry = data[0][1] # Assuming the first entry is [timestamp, value]
if first_entry is not None:
return 1
return 0
Настройка ответа @KamilCuk в соответствии с предложенной вами логикой:
def get_bids_for_pp(d):
return any(unit[1] is not None for ts in d["timeSeries"] for unit in ts['tsv']['data'])
Это вернет True
, если какая-либо из записей данных временного ряда не равна None. Я думаю, это то, что вам нужно, исходя из вашего псевдокода. Если вместо этого вы хотите вернуть True
, если все действительны (и ни один из них не null
), вы должны использовать all
вместо any
.
При этом используется выражение-генератор для фильтрации второго элемента данных. Он выполняет цикл for
в одном выражении. Он передает каждый элемент условному выражению unit[1] is not None
и генерирует список результатов. (На самом деле внутри он передает функцию, которая генерирует список результатов «на лету», а не сам список, но логика та же.) Он передает это в any
, который вернет True
, если какой-либо из элементов пройдены True
. Таким образом, вы получите ответ одним махом.
Вы всегда должны использоватьis not None
, а не != None
, как вы обнаружили, потому что None — такое особенное значение.
В этом коде предполагается, что data
— это список списков и что вы хотите сканировать второй элемент всех списков, возвращая True
, если какой-либо из них не является null
(т. е. если не все из них являются null
).
Если вы действительно хотите вернуть 1
или 0
(не рекомендуется; лучше использовать True
и False
), используйте
return 1 if any(unit[1] is not None for ts in d["timeSeries"] for unit in ts['tsv']['data']) else 0
is not
— это не «должен», а просто «следует». Даже PEP 8 так говорит.
Можете ли вы дать мне ссылку на PEP 8? Я поднял его, и там написано: «Сравнения с одиночными элементами, такими как None, всегда следует выполнять с помощью is или is not, но никогда с операторами равенства».
Это именно так. Какую дополнительную ссылку вы хотели бы?
Я скорректировал свой ответ, чтобы он соответствовал языку PEP 8. На самом деле там написано «должно всегда», что, на мой взгляд, отличается от «следует», поэтому я использовал этот язык. Спасибо за ваш комментарий.
«Всегда» — это странно. Это слово вообще не встречается в RFC 2119 , а слово «должен» там определяется словами «в определенных обстоятельствах могут существовать веские причины игнорировать конкретный элемент», чему «всегда» несколько противоречит. Это странно. Это примерно в 60% случаев это работает каждый раз.
Я думаю, что RFC 2119 ожидает, что слова, предназначенные для его соответствия, будут писаться с заглавной буквы. Другими словами, если бы PEP 8 сказал: «Сравнения с одиночными элементами, такими как None, ДОЛЖНЫ выполняться всегда...», ваше замешательство, безусловно, было бы оправдано. Другими словами, я утверждаю, что не каждое «должно» в стандарте предназначено для соответствия RFC 2119, даже если оно ДОЛЖНО.
Я так не думаю. Там даже написано: «Эти слова часто пишутся с заглавной буквы». И я подозреваю, что к настоящему времени даже это изменилось. И у меня сложилось впечатление, что RFC 2119 довольно часто упоминается/предназначается. Впервые я это заметил, кстати, даже не в компьютерном контексте, а в Регламенте WCA (о соревнованиях по сборке кубика Рубика и т. д., одно из моих хобби), см. раздел «Формулировки».
FIRST data element is not null (now it is 83)
первый элемент 1724846400, нет?