Introdução
Uma tarefa comum é processar itens em uma lista. Esta seção introduz as list comprehensions (compreensões de lista), uma ferramenta poderosa para fazer exatamente isso.
This tutorial is from open-source community. Access the source code
Uma tarefa comum é processar itens em uma lista. Esta seção introduz as list comprehensions (compreensões de lista), uma ferramenta poderosa para fazer exatamente isso.
Uma list comprehension (compreensão de lista) cria uma nova lista aplicando uma operação a cada elemento de uma sequência.
>>> a = [1, 2, 3, 4, 5]
>>> b = [2*x for x in a ]
>>> b
[2, 4, 6, 8, 10]
>>>
Outro exemplo:
>>> names = ['Elwood', 'Jake']
>>> a = [name.lower() for name in names]
>>> a
['elwood', 'jake']
>>>
A sintaxe geral é: [ <expressão> for <nome_da_variável> in <sequência> ].
Você também pode filtrar durante a list comprehension (compreensão de lista).
>>> a = [1, -5, 4, 2, -2, 10]
>>> b = [2*x for x in a if x > 0 ]
>>> b
[2, 8, 4, 20]
>>>
List comprehensions (compreensões de lista) são extremamente úteis. Por exemplo, você pode coletar valores de campos específicos de um dicionário:
stocknames = [s['name'] for s in stocks]
Você pode realizar consultas semelhantes a bancos de dados em sequências.
a = [s for s in stocks if s['price'] > 100 and s['shares'] > 50 ]
Você também pode combinar uma list comprehension (compreensão de lista) com uma redução de sequência:
cost = sum([s['shares']*s['price'] for s in stocks])
[ <expression> for <variable_name> in <sequence> if <condition>]
O que isso significa:
result = []
for variable_name in sequence:
if condition:
result.append(expression)
List comprehensions (compreensões de lista) vêm da matemática (notação de construtor de conjuntos).
a = [ x * x for x in s if x > 0 ] ## Python
a = { x^2 | x ∈ s, x > 0 } ## Math
Também é implementado em várias outras linguagens. A maioria dos programadores provavelmente não está pensando na aula de matemática, no entanto. Portanto, é aceitável vê-lo como um atalho de lista legal.
Experimente algumas compreensões de lista simples apenas para se familiarizar com a sintaxe.
>>> 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]
>>>
Observe como as compreensões de lista estão criando uma nova lista com os dados devidamente transformados ou filtrados.
Calcule o custo total do portfólio usando uma única instrução Python.
>>> portfolio = read_portfolio('portfolio.csv')
>>> cost = sum([ s['shares'] * s['price'] for s in portfolio ])
>>> cost
44671.15
>>>
Depois de fazer isso, mostre como você pode calcular o valor atual do portfólio usando uma única instrução.
>>> value = sum([ s['shares'] * prices[s['name']] for s in portfolio ])
>>> value
28686.1
>>>
Ambas as operações acima são um exemplo de map-reduction (mapeamento-redução). A compreensão de lista está mapeando uma operação em toda a lista.
>>> [ s['shares'] * s['price'] for s in portfolio ]
[3220.0000000000005, 4555.0, 12516.0, 10246.0, 3835.1499999999996, 3254.9999999999995, 7044.0]
>>>
A função sum() então realiza uma redução em todo o resultado:
>>> sum(_)
44671.15
>>>
Com este conhecimento, você está agora pronto para lançar uma empresa de startup de big data.
Experimente os seguintes exemplos de várias consultas de dados.
Primeiro, uma lista de todas as participações do portfólio com mais de 100 ações.
>>> 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}]
>>>
Todas as participações do portfólio para as ações MSFT e 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}]
>>>
Uma lista de todas as participações do portfólio que custam mais de $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}]
>>>
Mostre como você pode construir uma lista de tuplas (name, shares) onde name e shares são tomados de 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)]
>>>
Se você mudar os colchetes ([,]) para chaves ({, }), você obtém algo conhecido como set comprehension (compreensão de conjunto). Isso fornece valores únicos ou distintos.
Por exemplo, isso determina o conjunto de nomes de ações únicos que aparecem em portfolio:
>>> names = { s['name'] for s in portfolio }
>>> names
{ 'AA', 'GE', 'IBM', 'MSFT', 'CAT' }
>>>
Se você especificar pares key:value, você pode construir um dicionário. Por exemplo, crie um dicionário que mapeia o nome de uma ação para o número total de ações detidas.
>>> holdings = { name: 0 for name in names }
>>> holdings
{'AA': 0, 'GE': 0, 'IBM': 0, 'MSFT': 0, 'CAT': 0}
>>>
Este último recurso é conhecido como dictionary comprehension (compreensão de dicionário). Vamos tabular:
>>> for s in portfolio:
holdings[s['name']] += s['shares']
>>> holdings
{ 'AA': 100, 'GE': 95, 'IBM': 150, 'MSFT':250, 'CAT': 150 }
>>>
Experimente este exemplo que filtra o dicionário prices para apenas aqueles nomes que aparecem no portfólio:
>>> 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}
>>>
Saber como usar várias combinações de list, set e dictionary comprehensions (compreensões de lista, conjunto e dicionário) pode ser útil em várias formas de processamento de dados. Aqui está um exemplo que mostra como extrair colunas selecionadas de um arquivo CSV.
Primeiro, leia uma linha de informações de cabeçalho de um arquivo CSV:
>>> import csv
>>> f = open('portfoliodate.csv')
>>> rows = csv.reader(f)
>>> headers = next(rows)
>>> headers
['name', 'date', 'time', 'shares', 'price']
>>>
Em seguida, defina uma variável que lista as colunas que você realmente se importa:
>>> select = ['name', 'shares', 'price']
>>>
Agora, localize os índices das colunas acima no arquivo CSV de origem:
>>> indices = [ headers.index(colname) for colname in select ]
>>> indices
[0, 3, 4]
>>>
Finalmente, leia uma linha de dados e transforme-a em um dicionário usando uma dictionary comprehension (compreensão de dicionário):
>>> row = next(rows)
>>> record = { colname: row[index] for colname, index in zip(select, indices) } ## dict-comprehension
>>> record
{'price': '32.20', 'name': 'AA', 'shares': '100'}
>>>
Se você está se sentindo confortável com o que acabou de acontecer, leia o resto do arquivo:
>>> 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'}]
>>>
Nossa, você acabou de reduzir grande parte da função read_portfolio() a uma única instrução.
List comprehensions (compreensões de lista) são comumente usadas em Python como um meio eficiente para transformar, filtrar ou coletar dados. Devido à sintaxe, você não deve exagerar --- tente manter cada list comprehension o mais simples possível. Não há problema em dividir as coisas em várias etapas. Por exemplo, não é claro que você gostaria de apresentar o último exemplo aos seus colegas de trabalho desavisados.
Dito isso, saber como manipular dados rapidamente é uma habilidade incrivelmente útil. Existem inúmeras situações em que você pode ter que resolver algum tipo de problema pontual envolvendo importações, exportações, extração de dados e assim por diante. Tornar-se um mestre guru de list comprehensions pode reduzir substancialmente o tempo gasto na criação de uma solução. Além disso, não se esqueça do módulo collections.
Parabéns! Você concluiu o laboratório de List Comprehensions (compreensões de lista). Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.