Фильтровать словарь по элементу boolean — API Python

#python #api

#python #API

Вопрос:

Я новичок в Python и пытаюсь отфильтровать словарь по элементу. Шаги для воспроизведения:

 import requests

# Get a list of planets and convert from Json.
space = requests.get("https://api.le-systeme-solaire.net/rest/bodies/")
arr = space.json()

# Select only planets.
{k:v for (k,v) in arr.items() if isPlanet == True}
  

Ошибка:

 NameError: global name 'isPlanet' is not defined
  

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

Ответ №1:

Полученный вами ответ JSON представляет собой dict с одним ключом: value . ключ bodies — это, а значение — это список dicts.

 import requests
from pprint import pprint

# Get request with JSON response.
response = requests.get("https://api.le-systeme-solaire.net/rest/bodies/")
data = response.json()

# Make a list with the planets.
planets = [item for item in data['bodies'] if item.get("isPlanet")]
pprint(planets)
  

вывод

 [{'alternativeName': 'A899 OF - 1943 XB',
  'aphelion': 445410000,
  'aroundPlanet': None,
  'axialTilt': 3,
  'density': 2.161,
  'dimension': '',
  'discoveredBy': 'Giuseppe Piazzi',
  'discoveryDate': '01/01/1801',
  'eccentricity': 0.07582,
  'englishName': '1 Ceres',
  'equaRadius': 487.0,
  'escape': 510.0,
  'flattening': 0.9619,
  'gravity': 0.28,
  'id': 'ceres',
  'inclination': 10.593,
  'isPlanet': True,
  'mass': {'massExponent': 20, 'massValue': 9.393},
  'meanRadius': 476.2,
  'moons': None,
  'name': '(1) Cérès',
  'perihelion': 382620000,
  'polarRadius': 455.0,
  'rel': 'https://api.le-systeme-solaire.net/rest/bodies/ceres',
  'semimajorAxis': 413690250,
  'sideralOrbit': 1681.63,
  'sideralRotation': 9.07,
  'vol': {'volExponent': 9, 'volValue': 4.21}},
 {'alternativeName': '2003 UB313',
  'aphelion': 14594512904,
  'aroundPlanet': None,
  'axialTilt': 0,
  'density': 2.52,
  'dimension': '',
  'discoveredBy': 'Michael E. Brown, Chadwick Trujillo, David L. Rabinowitz',
  'discoveryDate': '05/01/2005',
  'eccentricity': 0.44068,
  'englishName': '136199 Eris',
  'equaRadius': 0.0,
  'escape': 1380.0,
  'flattening': 0.0,
  'gravity': 0.82,
  'id': 'eris',
  'inclination': 44.0445,
  'isPlanet': True,
  'mass': {'massExponent': 22, 'massValue': 1.66},
  'meanRadius': 1163.0,
  'moons': [{'moon': 'Dysnomie',
             'rel': 'https://api.le-systeme-solaire.net/rest/bodies/dysnomie'}],
  'name': '(136199) Éris',
  'perihelion': 5765732799,
  'polarRadius': 0.0,
  'rel': 'https://api.le-systeme-solaire.net/rest/bodies/eris',
  'semimajorAxis': 10180122852,
  'sideralOrbit': 203830.0,
  'sideralRotation': 25.92,
  'vol': {'volExponent': 9, 'volValue': 6.59}},

... rest of list elements skipped for brevity ...
]
  

кроме того, API предоставляет вам возможность фильтровать данные, которые вы получаете, на основе определенных критериев (т. Е. Вы можете фильтровать данные, которые вы получаете в ответ), однако есть ошибка с filter[]=isPlanet,eq,true (см. https://github.com/systeme-solaire/api-rest/issues/3 ).

 import requests

# Get a list of planets and convert from Json.
params = {'filter[]':'isPlanet,neq,false'}

response = requests.get("https://api.le-systeme-solaire.net/rest/bodies", params=params)
data = response.json()
planets = data.get('bodies')
# print just len of planets list
print(len(planets))
  

Ответ №2:

возможно, вы ищете что-то подобное.

 [v for v in arr['bodies'] if (v['isPlanet'] == True)]
  

arr['bodies'] вернет вам список всех тел

v['isPlanet'] позволяет получить доступ к этому ключу в словаре

Нет смысла делать arr.items() , поскольку arr имеет только один ключ ( bodies )

{} заменяется на [] , поэтому мы получаем список вместо словаря в качестве выходных данных