Введение
В этом разделе рассматриваются списки, словари и множества.
This tutorial is from open-source community. Access the source code
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
В этом разделе рассматриваются списки, словари и множества.
Программы часто должны работать с множеством объектов.
Имеются три основных варианта использования.
Используйте список, когда порядок данных имеет значение. Помните, что списки могут содержать любые виды объектов. Например, список кортежей.
portfolio = [
('GOOG', 100, 490.1),
('IBM', 50, 91.3),
('CAT', 150, 83.44)
]
portfolio[0] ## ('GOOG', 100, 490.1)
portfolio[2] ## ('CAT', 150, 83.44)
Создание списка с нуля.
records = [] ## Инициализация пустого списка
## Используйте.append(), чтобы добавить больше элементов
records.append(('GOOG', 100, 490.10))
records.append(('IBM', 50, 91.3))
...
Пример чтения записей из файла.
records = [] ## Инициализация пустого списка
with open('portfolio.csv', 'rt') as f:
next(f) ## Пропустить заголовок
for line in f:
row = line.split(',')
records.append((row[0], int(row[1]), float(row[2])))
Словари полезны, если вы хотите быстро осуществлять случайный поиск (по имени ключа). Например, словарь цен на акции:
prices = {
'GOOG': 513.25,
'CAT': 87.22,
'IBM': 93.37,
'MSFT': 44.12
}
Вот некоторые простые поиски:
>>> prices['IBM']
93.37
>>> prices['GOOG']
513.25
>>>
Пример создания словаря с нуля.
prices = {} ## Инициализация пустого словаря
## Вставка новых элементов
prices['GOOG'] = 513.25
prices['CAT'] = 87.22
prices['IBM'] = 93.37
Пример заполнения словаря содержимым файла.
prices = {} ## Инициализация пустого словаря
with open('prices.csv', 'rt') as f:
for line in f:
row = line.split(',')
prices[row[0]] = float(row[1])
Примечание: Если вы попытаетесь это сделать с файлом prices.csv
, вы обнаружите, что почти все работает - в конце есть пустая строка, которая приводит к сбою. Вам нужно найти какой-то способ изменить код, чтобы учесть это (см. упражнение 2.6).
Вы можете проверить существование ключа.
if key in d:
## ДА
else:
## НЕТ
Вы можете искать значение, которое может не существовать, и указать значение по умолчанию, если оно отсутствует.
name = d.get(key, default)
Пример:
>>> prices.get('IBM', 0.0)
93.37
>>> prices.get('SCOX', 0.0)
0.0
>>>
Почти любой тип значения может быть использован в качестве ключа словаря в Python. Ключ словаря должен быть неизменяемым типом. Например, кортежи:
holidays = {
(1, 1) : 'Новый год',
(3, 14) : 'День Пи',
(9, 13) : "День программиста",
}
Затем для доступа:
>>> holidays[3, 14]
'День Пи'
>>>
Ни список, ни множество, ни другой словарь не могут служить ключом словаря, потому что списки и словари являются изменяемыми.
Множества - это коллекции неупорядоченных уникальных элементов.
tech_stocks = { 'IBM','AAPL','MSFT' }
## Альтернативный синтаксис
tech_stocks = set(['IBM', 'AAPL', 'MSFT'])
Множества полезны для проверки принадлежности элемента.
>>> tech_stocks
set(['AAPL', 'IBM', 'MSFT'])
>>> 'IBM' in tech_stocks
True
>>> 'FB' in tech_stocks
False
>>>
Множества также полезны для удаления дубликатов.
names = ['IBM', 'AAPL', 'GOOG', 'IBM', 'GOOG', 'YHOO']
unique = set(names)
## unique = set(['IBM', 'AAPL','GOOG','YHOO'])
Дополнительные операции с множествами:
unique.add('CAT') ## Добавить элемент
unique.remove('YHOO') ## Удалить элемент
s1 = { 'a', 'b', 'c'}
s2 = { 'c', 'd' }
s1 | s2 ## Объединение множеств { 'a', 'b', 'c', 'd' }
s1 & s2 ## Пересечение множеств { 'c' }
s1 - s2 ## Разность множеств { 'a', 'b' }
В этих упражнениях вы начинаете создавать одну из основных программ, используемых на протяжении всего курса. Выполняйте задания в файле report.py
.
Файл portfolio.csv
содержит список акций в портфеле. В упражнении 1.30 вы написали функцию portfolio_cost(filename)
, которая читала этот файл и выполняла простые вычисления.
Ваш код должен был выглядеть примерно так:
## pcost.py
import csv
def portfolio_cost(filename):
'''Вычисляет общую стоимость (количество акций * цена) файла портфеля'''
total_cost = 0.0
with open(filename, 'rt') as f:
rows = csv.reader(f)
headers = next(rows)
for row in rows:
nshares = int(row[1])
price = float(row[2])
total_cost += nshares * price
return total_cost
Используя этот код в качестве ориентира, создайте новый файл report.py
. В этом файле определите функцию read_portfolio(filename)
, которая открывает заданный файл портфеля и читает его в список кортежей. Для этого вам нужно сделать несколько небольших изменений в коде выше.
Во - первых, вместо определения total_cost = 0
вы создадите переменную, которая изначально будет равна пустому списку. Например:
portfolio = []
Далее, вместо суммирования стоимости, вы превратите каждую строку в кортеж точно так же, как вы делали это в предыдущем упражнении, и добавьте его в этот список. Например:
for row in rows:
holding = (row[0], int(row[1]), float(row[2]))
portfolio.append(holding)
Наконец, вы вернете полученный список portfolio
.
Протестируйте свою функцию интерактивно (напомним, что для этого вам сначала нужно запустить программу report.py
в интерпретаторе):
Подсказка: используйте -i
при выполнении файла в терминале
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> portfolio
[('AA', 100, 32.2), ('IBM', 50, 91.1), ('CAT', 150, 83.44), ('MSFT', 200, 51.23),
('GE', 95, 40.37), ('MSFT', 50, 65.1), ('IBM', 100, 70.44)]
>>>
>>> portfolio[0]
('AA', 100, 32.2)
>>> portfolio[1]
('IBM', 50, 91.1)
>>> portfolio[1][1]
50
>>> total = 0.0
>>> for s in portfolio:
total += s[1] * s[2]
>>> print(total)
44671.15
>>>
Этот список кортежей, который вы создали, очень похож на двумерный массив. Например, вы можете получить доступ к определенной колонке и строке с помощью обращения вида portfolio[row][column]
, где row
и column
- целые числа.
Тем не менее, вы также можете переписать последний цикл for с использованием такого выражения:
>>> total = 0.0
>>> for name, shares, price in portfolio:
total += shares*price
>>> print(total)
44671.15
>>>
Возьмите функцию, которую вы написали в упражнении 2.4, и модифицируйте ее так, чтобы каждый акция в портфеле представлялась словарем, а не кортежем. В этом словаре используйте имена полей "name", "shares" и "price", чтобы представить разные колонки в входном файле.
Протестируйте эту новую функцию так же, как вы делали это в упражнении 2.4.
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> portfolio
[{'name': 'AA','shares': 100, 'price': 32.2}, {'name': 'IBM','shares': 50, 'price': 91.1},
{'name': 'CAT','shares': 150, 'price': 83.44}, {'name': 'MSFT','shares': 200, 'price': 51.23},
{'name': 'GE','shares': 95, 'price': 40.37}, {'name': 'MSFT','shares': 50, 'price': 65.1},
{'name': 'IBM','shares': 100, 'price': 70.44}]
>>> portfolio[0]
{'name': 'AA','shares': 100, 'price': 32.2}
>>> portfolio[1]
{'name': 'IBM','shares': 50, 'price': 91.1}
>>> portfolio[1]['shares']
50
>>> total = 0.0
>>> for s in portfolio:
total += s['shares']*s['price']
>>> print(total)
44671.15
>>>
Здесь вы заметите, что разные поля для каждой записи доступа по именам ключей, а не по числовым номерам колонок. Это часто предпочтительнее, потому что результирующий код легче читать позднее.
Просмотр больших словарей и списков может быть запутанным. Чтобы очистить вывод для отладки, рассмотрите использование функции pprint
.
>>> from pprint import pprint
>>> pprint(portfolio)
[{'name': 'AA', 'price': 32.2,'shares': 100},
{'name': 'IBM', 'price': 91.1,'shares': 50},
{'name': 'CAT', 'price': 83.44,'shares': 150},
{'name': 'MSFT', 'price': 51.23,'shares': 200},
{'name': 'GE', 'price': 40.37,'shares': 95},
{'name': 'MSFT', 'price': 65.1,'shares': 50},
{'name': 'IBM', 'price': 70.44,'shares': 100}]
>>>
Словарь - это полезный способ отслеживать элементы, когда вы хотите искать элементы с использованием индекса, отличного от целого числа. В оболочке Python попробуйте работать со словарем:
>>> prices = { }
>>> prices['IBM'] = 92.45
>>> prices['MSFT'] = 45.12
>>> prices
... посмотрите на результат...
>>> prices['IBM']
92.45
>>> prices['AAPL']
... посмотрите на результат...
>>> 'AAPL' in prices
False
>>>
Файл prices.csv
содержит серию строк с ценами на акции. Файл выглядит примерно так:
"AA",9.22
"AXP",24.85
"BA",44.85
"BAC",11.27
"C",3.72
...
Напишите функцию read_prices(filename)
, которая считывает набор цен, подобный этому, в словарь, где ключами словаря являются имена акций, а значениями словаря - цены на акции.
Для этого начните с пустого словаря и начинайте вставлять значения в него так же, как вы делали выше. Однако теперь вы читаете значения из файла.
Мы будем использовать эту структуру данных для быстрого поиска цены на заданное имя акции.
Несколько небольших советов, которые вам понадобятся для этой части. Во - первых, убедитесь, что используете модуль csv
так же, как и раньше - здесь нет необходимости изобретать велосипед.
>>> import csv
>>> f = open('/home/labex/project/prices.csv', 'r')
>>> rows = csv.reader(f)
>>> for row in rows:
print(row)
['AA', '9.22']
['AXP', '24.85']
...
[]
>>>
Другая небольшая сложность заключается в том, что файл prices.csv
может содержать некоторые пустые строки. Обратите внимание, как последняя строка данных выше - это пустой список, что означает, что на этой строке не было данных.
Возможно, это может привести к тому, что ваша программа завершится с исключением. Используйте инструкции try
и except
, чтобы обработать это соответствующим образом. Взгляните: не лучше ли предотвратить плохие данные с использованием if
- инструкции вместо этого?
После того, как вы напишете функцию read_prices()
, протестируйте ее интерактивно, чтобы убедиться, что она работает:
>>> prices = read_prices('/home/labex/project/prices.csv')
>>> prices['IBM']
106.28
>>> prices['MSFT']
20.89
>>>
Объедините все эти работы, добавив несколько дополнительных инструкций в вашу программу report.py
, которая вычисляет прибыль/убыток. Эти инструкции должны использовать список акций из упражнения 2.5 и словарь цен из упражнения 2.6 и вычислять текущую стоимость портфеля, а также прибыль/убыток.
Поздравляем! Вы завершили лабораторную работу по контейнерам. Вы можете практиковаться в других лабораторных работах в LabEx, чтобы улучшить свои навыки.