Скопируйте файл population_data.json, содержащий данные о численности населения большинства стран мира с 1960 по 2010 год, в каталог с программами этой главы. Информация взята из многочисленных наборов данных, бесплатно публикуемых фондом Open Knowledge Foundation (http://data.okfn.org/).

<p>Извлечение необходимых данных</p>

Взглянем на файл population_data.json и попробуем понять, как взяться за обработку данных файла:

population_data.json

[

{

. ."Country Name": "Arab World",

. ."Country Code": "ARB",

. ."Year": "1960",

. ."Value": "96388069"

},

{

. ."Country Name": "Arab World",

. ."Country Code": "ARB",

. ."Year": "1961",

. ."Value": "98882541.4"

},

...

]

Фактически перед нами один длинный список Python. Каждый элемент списка представляет собой словарь с четырьмя ключами: название страны (Country Name), код страны (Country Code), год (Year) и значение (Value), представляющее численность населения. В нашей программе будут использоваться названия стран и численность населения только за 2010 год, поэтому для начала напишем программу, которая выводит только эту информацию:

world_population.py

import json

# Список заполняется данными.

filename = 'population_data.json'

with open(filename) as f:

(1) . .pop_data = json.load(f)

# Вывод населения каждой страны за 2010 год.

(2)for pop_dict in pop_data:

(3) . .if pop_dict['Year'] == '2010':

(4) . . . .country_name = pop_dict['Country Name']

. . . .population = pop_dict['Value']

. . . .print(country_name + ": " + population)

Сначала программа импортирует модуль json, чтобы иметь возможность загружать данные из файла. Загруженные данные сохраняются в списке pop_data (1) . Функция json.load() преобразует данные в формат, с которым может работать Python: в данном случае это список. В точке (2) создается цикл, перебирающий все элементы pop_data. Каждый элемент представляет собой словарь с четырьмя парами «ключ—значение», который сохраняется в переменной pop_dict.

В точке (3) ключ 'Year' каждого словаря проверяется на значение 2010. (Так как все значения population_data.json заключены в кавычки, выполняется сравнение строк.) Если словарь относится к 2010 году, то значение, связанное с ключом 'Country Name', сохраняется в переменной country_name, а значение, связанное с ключом 'Value', сохраняется в переменной population (4). Затем программа выводит название каждой страны и ее население.

Программа выводит последовательность названий стран и численности их населения:

Arab World: 357868000

Caribbean small states: 6880000

East Asia & Pacific (all income levels): 2201536674

...

Zimbabwe: 12571000

Не все данные включают точные названия стран, но это неплохое начало для дальнейшей работы. Теперь данные необходимо преобразовать в формат, с которым может работать Pygal.

<p>Преобразование строк в числовые значения</p>

Все ключи и значения в population_data.json хранятся в строковом формате. Чтобы работать с данными численности населения, необходимо преобразовать строковые значения в числа. Для этого в программе используется функция int():

world_population.py

...

for pop_dict in pop_data:

if pop_dict['Year'] == '2010':

country_name = pop_dict['Country Name']

(1) . . . .population = int(pop_dict['Value'])

(2) . . . .print(country_name + ": " + str(population))

После преобразования (1) все данные численности населения хранятся в числовом формате. При выводе численность населения должна быть преобразована в ­строку (2). Впрочем, для некоторых значений это изменение приводит к ошибке:

Arab World: 357868000

Caribbean small states: 6880000

East Asia & Pacific (all income levels): 2201536674

...

Traceback (most recent call last):

File "print_populations.py", line 12, in

. .population = int(pop_dict['Value'])

(1) ValueError: invalid literal for int() with base 10: '1127437398.85751'

Необработанные данные часто форматируются непоследовательно, поэтому ошибки в них встречаются достаточно часто. В данном случае ошибка происходит из-за того, что Python не может преобразовать строку с дробным значением '1127437398.85751' в целое число (1) . (Вероятно, дробное значение было получено в результате интерполяции в те годы, в которые перепись населения не производилась.) Чтобы решить эту проблему, мы сначала преобразуем строку в вещественное число, а затем преобразуем вещественное число в целое:

world_population.py

...

for pop_dict in pop_data:

if pop_dict['Year'] == '2010':

country = pop_dict['Country Name']

. . . .population = int(float(pop_dict['Value']))

print(country + ": " + str(population))

Функция float() преобразует строку в целое число, а функция int() отсекает дробную часть и возвращает целое число. Теперь можно вывести полный набор данных численности населения за 2010 год без ошибок:

Arab World: 357868000

Caribbean small states: 6880000

East Asia & Pacific (all income levels): 2201536674

...

Zimbabwe: 12571000

Перейти на страницу:

Все книги серии Библиотека программиста

Похожие книги