Введение
Одной из распространенных задач является обработка элементов в списке. В этом разделе рассматриваются списочные выражения, мощный инструмент для выполнения именно этой задачи.
This tutorial is from open-source community. Access the source code
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
Одной из распространенных задач является обработка элементов в списке. В этом разделе рассматриваются списочные выражения, мощный инструмент для выполнения именно этой задачи.
Списочное выражение создает новый список, применяя операцию к каждому элементу последовательности.
>>> a = [1, 2, 3, 4, 5]
>>> b = [2*x for x in a ]
>>> b
[2, 4, 6, 8, 10]
>>>
Другой пример:
>>> names = ['Elwood', 'Jake']
>>> a = [name.lower() for name in names]
>>> a
['elwood', 'jake']
>>>
Общая синтаксис: [ <выражение> for <имя_переменной> in <последовательность> ]
.
Вы также можете фильтровать элементы при создании списочного выражения.
>>> a = [1, -5, 4, 2, -2, 10]
>>> b = [2*x for x in a if x > 0 ]
>>> b
[2, 8, 4, 20]
>>>
Списочные выражения чрезвычайно полезны. Например, вы можете собрать значения определенных полей словаря:
stocknames = [s['name'] for s in stocks]
Вы можете выполнять запросы, подобные запросам к базе данных, к последовательностям.
a = [s for s in stocks if s['price'] > 100 and s['shares'] > 50 ]
Вы также можете комбинировать списочное выражение с редукцией последовательности:
cost = sum([s['shares']*s['price'] for s in stocks])
[ <выражение> for <имя_переменной> in <последовательность> if <условие>]
Что это означает:
result = []
for variable_name in sequence:
if condition:
result.append(expression)
Списочные выражения произошли из математики (запись множества).
a = [ x * x for x in s if x > 0 ] ## Python
a = { x^2 | x ∈ s, x > 0 } ## Математика
Это также реализовано в нескольких других языках. Однако большинство программистов, вероятно, не думают о своих уроках математики. Поэтому можно рассматривать его как удобный способ создания списков.
Попробуйте несколько простых списочных выражений, чтобы просто привыкнуть к синтаксису.
>>> nums = [1,2,3,4]
>>> squares = [ x * x for x in nums ]
>>> squares
[1, 4, 9, 16]
>>> twice = [ 2 * x for x in nums if x > 2 ]
>>> twice
[6, 8]
>>>
Заметьте, как списочные выражения создают новый список с данными, которые были соответствующим образом преобразованы или отфильтрованы.
Вычислите общую стоимость портфеля с использованием одного Python-выражения.
>>> portfolio = read_portfolio('portfolio.csv')
>>> cost = sum([ s['shares'] * s['price'] for s in portfolio ])
>>> cost
44671.15
>>>
После этого покажите, как можно вычислить текущую стоимость портфеля с использованием одного выражения.
>>> value = sum([ s['shares'] * prices[s['name']] for s in portfolio ])
>>> value
28686.1
>>>
Оба вышеперечисленных действия являются примерами map-редукции. Списочное выражение отображает операцию по всему списку.
>>> [ s['shares'] * s['price'] for s in portfolio ]
[3220.0000000000005, 4555.0, 12516.0, 10246.0, 3835.1499999999996, 3254.9999999999995, 7044.0]
>>>
Затем функция sum()
выполняет редукцию по результату:
>>> sum(_)
44671.15
>>>
С этой информацией вы теперь готовы создать свою стартап-ком를анию в области больших данных.
Попробуйте следующие примеры различных запросов к данным.
Во - первых, список всех позиций портфеля с количеством акций более 100.
>>> more100 = [ s for s in portfolio if s['shares'] > 100 ]
>>> more100
[{'price': 83.44, 'name': 'CAT','shares': 150}, {'price': 51.23, 'name': 'MSFT','shares': 200}]
>>>
Все позиции портфеля для акций MSFT и IBM.
>>> msftibm = [ s for s in portfolio if s['name'] in {'MSFT','IBM'} ]
>>> msftibm
[{'price': 91.1, 'name': 'IBM','shares': 50}, {'price': 51.23, 'name': 'MSFT','shares': 200},
{'price': 65.1, 'name': 'MSFT','shares': 50}, {'price': 70.44, 'name': 'IBM','shares': 100}]
>>>
Список всех позиций портфеля, стоимость которых превышает 10000 долларов.
>>> cost10k = [ s for s in portfolio if s['shares'] * s['price'] > 10000 ]
>>> cost10k
[{'price': 83.44, 'name': 'CAT','shares': 150}, {'price': 51.23, 'name': 'MSFT','shares': 200}]
>>>
Покажите, как можно создать список кортежей (name, shares)
, где name
и shares
берутся из portfolio
.
>>> name_shares =[ (s['name'], s['shares']) for s in portfolio ]
>>> name_shares
[('AA', 100), ('IBM', 50), ('CAT', 150), ('MSFT', 200), ('GE', 95), ('MSFT', 50), ('IBM', 100)]
>>>
Если вы замените квадратные скобки ([
, ]
) на фигурные ({
, }
), вы получите что - то, называемое сочетанием множеств (set comprehension). Это дает вам уникальные или неповторяющиеся значения.
Например, это определяет множество уникальных имен акций, которые появляются в portfolio
:
>>> names = { s['name'] for s in portfolio }
>>> names
{ 'AA', 'GE', 'IBM', 'MSFT', 'CAT' }
>>>
Если вы указываете пары ключ:значение
, вы можете создать словарь. Например, создайте словарь, который сопоставляет имя акции с общим количеством акций, которые куплены.
>>> holdings = { name: 0 for name in names }
>>> holdings
{'AA': 0, 'GE': 0, 'IBM': 0, 'MSFT': 0, 'CAT': 0}
>>>
Последующая особенность называется сочетанием словарей (dictionary comprehension). Давайте составим таблицу:
>>> for s in portfolio:
holdings[s['name']] += s['shares']
>>> holdings
{ 'AA': 100, 'GE': 95, 'IBM': 150, 'MSFT':250, 'CAT': 150 }
>>>
Попробуйте этот пример, который фильтрует словарь prices
так, чтобы остались только те имена, которые появляются в портфеле:
>>> portfolio_prices = { name: prices[name] for name in names }
>>> portfolio_prices
{'AA': 9.22, 'GE': 13.48, 'IBM': 106.28, 'MSFT': 20.89, 'CAT': 35.46}
>>>
Знание, как использовать различные комбинации списочных, множественных и словарных включений, может быть полезно при различных формах обработки данных. Вот пример, который показывает, как извлекать выбранные столбцы из CSV-файла.
Во - первых, прочитайте строку с информацией о заголовках из CSV-файла:
>>> import csv
>>> f = open('portfoliodate.csv')
>>> rows = csv.reader(f)
>>> headers = next(rows)
>>> headers
['name', 'date', 'time','shares', 'price']
>>>
Далее, определите переменную, которая перечисляет столбцы, которые вас на самом деле интересуют:
>>> select = ['name','shares', 'price']
>>>
Теперь, определите индексы вышеперечисленных столбцов в исходном CSV-файле:
>>> indices = [ headers.index(colname) for colname in select ]
>>> indices
[0, 3, 4]
>>>
Наконец, прочитайте строку данных и превратите ее в словарь с использованием словарного включения:
>>> row = next(rows)
>>> record = { colname: row[index] for colname, index in zip(select, indices) } ## dict-comprehension
>>> record
{'price': '32.20', 'name': 'AA','shares': '100'}
>>>
Если вы чувствуете себя комфортно с тем, что только произошло, прочитайте остальную часть файла:
>>> portfolio = [ { colname: row[index] for colname, index in zip(select, indices) } for row in rows ]
>>> portfolio
[{'price': '91.10', 'name': 'IBM','shares': '50'}, {'price': '83.44', 'name': 'CAT','shares': '150'},
{'price': '51.23', 'name': 'MSFT','shares': '200'}, {'price': '40.37', 'name': 'GE','shares': '95'},
{'price': '65.10', 'name': 'MSFT','shares': '50'}, {'price': '70.44', 'name': 'IBM','shares': '100'}]
>>>
О, боже мой, вы только что свели большую часть функции read_portfolio()
до одного выражения.
Списочные включения (list comprehensions) широко используются в Python в качестве эффективного средства для преобразования, фильтрации или сбора данных. В силу синтаксиса, не стоит переусердствовать - старайтесь держать каждое списочное включение как можно проще. Можно разбить задачу на несколько шагов. Например, неясно, стоит ли показывать последний пример неожиданным коллегам.
Тем не менее, знание способов быстрого манипулирования данными - это навык, который чрезвычайно полезен. В многочисленных ситуациях может потребоваться решить какой - то一次性 (one - off) 问题, связанный с импортом, экспортом, извлечением данных и т.д. Стать гуру списочных включений может значительно сократить время, затрачиваемое на разработку решения. Также не забывайте про модуль collections
.
Поздравляем! Вы завершили лабораторную работу по списочным включениям. Вы можете практиковаться в других лабораторных работах в LabEx, чтобы улучшить свои навыки.