关于python:翻译实用的Python编程0206Listcomprehension

41次阅读

共计 4431 个字符,预计需要花费 12 分钟才能阅读完成。

目录 | 上一节 (2.5 collections 模块) | [下一节 (2.7 对象模型)]()

2.6 列表推导式

一个常见的工作是解决列表中的项(译注:元素)。本节介绍列表推导式,实现此工作的弱小工具。

创立新列表

列表推导式通过将操作利用于序列的每一个元素来创立新列表。

>>> 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']
>>>

列表推导式的个别语法是:[<expression> for <variable_name> in <sequence>]

过滤

也能够在列表推导式中对元素进行过滤。

>>> 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])

个别语法

[<expression> for <variable_name> in <sequence> if <condition>]

下面语法的含意:

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}         # Math

这在其它几种语言中也实现了,尽管大部分的程序员可能曾经想不起他们的数学课了。所以,能够将其视为很酷的列表快捷方式。

练习

首先运行 report.py 程序,以便可能在交互模式下中加载股票投资组合。

bash % python3 -i report.py

当初,在 Python 交互提示符下,输出语句以执行下述操作。这些操作对投资组合数据执行各类缩减,转换和查找。

练习 2.19:列表推导式

尝试一些简略的列表推导式来相熟语法:

>>> 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]
>>>

请留神列表推导式是如何通过适当转换或过滤的数据创立一个新列表的。

练习 2.20:序列缩减

应用单个 Python 语句计算投资组合的总价。

>>> portfolio = read_portfolio('Data/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
>>>

下面的两个操作都是映射缩减的列子。列表推导式将操作映射到整个列表。

>>> [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
>>>

有了这些常识,你当初就能够筹备成立一家大数据守业公司了。

练习 2.21:数据查问

请尝试以下各种数据查问示例。

首选是创立一个列表,存储持有 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}]
>>>

练习 2.22:数据提取

展现如何构建元组 (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)]
>>>

如果将方括号([,])更改为花括号({, }),那么将失去汇合推导式。这会失去举世无双的的或无反复的值。

例如,这将确定汇合中的股票名称是举世无双的:

>>> names = {s['name'] for s in portfolio }
>>> names
{'AA', 'GE', 'IBM', 'MSFT', 'CAT'}
>>>

如果指定键值对(key:value),则能够构建一个字典。例如,构建一个将股票名称映射到持有的股票数量的字典:

>>> holdings = {name: 0 for name in names}
>>> holdings
{'AA': 0, 'GE': 0, 'IBM': 0, 'MSFT': 0, 'CAT': 0}
>>>

前面的个性就是众所皆知的字典推导式。让咱们将其表格化:

>>> for s in portfolio:
        holdings[s['name']] += s['shares']

>>> holdings
{'AA': 100, 'GE': 95, 'IBM': 150, 'MSFT':250, 'CAT': 150}
>>>

请尝试以下示例,该示例将 prices 字典过滤出仅在 portfolio 中呈现的名称(name):

>>> 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}
>>>

练习 2.23: 从 CSV 文件提取数据

在各类数据处理中,晓得如何将列表,汇合,字典推导式联结应用会十分有用。这里有一个示例,展现如何从 CSV 文件中提取所抉择的列。

首先,从 CSV 文件读取一行题目信息:

>>> import csv
>>> f = open('Data/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() 函数简化为单个语句了。

阐明

列表推导式在 Python 中常用作转换,过滤和收集数据的无效办法。因为语法的起因,请不要走极端——应该让每个列表推导式尽可能简略。能够将事件合成为多个步骤。例如,不分明你会不会把最初一个例子强加给毫不知情的共事。

也就是说,晓得如何疾速解决数据是一项十分有用的技能。在很多状况下,可能必须解决某种一次性的问题,包含数据导入,导出,提取等。成为列表推导式的巨匠能够大大减少设计方案所破费的工夫。另外,不要遗记 collections 模块。

目录 | 上一节 (2.5 collections 模块) | [下一节 (2.7 对象模型)]()

注:残缺翻译见 https://github.com/codists/practical-python-zh

正文完
 0