翻译:《实用的 Python 编程》02_02_Containers - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
codists

翻译:《实用的 Python 编程》02_02_Containers

  •  
  •   codists
    codists 2021 年 2 月 21 日 1885 次点击
    这是一个创建于 1888 天前的主题,其中的信息可能已经有所发展或是发生改变。

    2.2 容器

    本节讨论列表( list ),字典( dict )和集合( set )。

    概述

    通常,程序必须处理许多对象。

    • 股票的投资组合
    • 股票价格表

    这里有三种主要的选择(译注:数据结构)可以使用:

    • 列表。有序的数据。
    • 字典。无序的数据。
    • 集合。互异且无序的数据。

    把列表当作容器

    当数据顺序很重要时,请使用列表。记住,列表可以存储任何类型的对象。例如,包含元组的列表:

    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 = [] # Initial empty list # Use .append() to add more items records.append(('GOOG', 100, 490.10)) records.append(('IBM', 50, 91.3)) ... 

    从文件读取记录的示例:

    records = [] # Initial empty list with open('Data/portfolio.csv', 'rt') as f: next(f) # Skip header 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 = {} # Initial empty dict # Insert new items prices['GOOG'] = 513.25 prices['CAT'] = 87.22 prices['IBM'] = 93.37 

    从文件内容填充字典的示例:

    prices = {} # Initial empty dict with open('Data/prices.csv', 'rt') as f: for line in f: row = line.split(',') prices[row[0]] = float(row[1]) 

    注意:如果是在 Data/prices.csv 文件上尝试此操作,会发现几乎可以正常工作但是,在末尾有一个空行导致程序崩溃了。需要找出一些方法来修改代码以解决此问题(参见练习 2.6 )。

    字典查找

    测试键是否存在:

    if key in d: # YES else: # NO 

    可以查找可能不存在的值,并在值不存在的情况下提供默认值。

    name = d.get(key, default) 

    示例:

    >>> prices.get('IBM', 0.0) 93.37 >>> prices.get('SCOX', 0.0) 0.0 >>> 

    组合键

    在 P ython 中,几乎任何类型的值都可以用作字典的键。字典的键必须是不可变类型。例如,元组:

    holidays = { (1, 1) : 'New Years', (3, 14) : 'Pi day', (9, 13) : "Programmer's day", } 

    然后访问:

    >>> holidays[3, 14] 'Pi day' >>> 

    列表,集合或者其它字典都不能用作字典的键,因为列表和字典(译注:集合也是使用哈希技术实现的)是可变的。

    集合

    集合是互异且无序的数据。

    tech_stocks= { 'IBM','AAPL','MSFT' } # Alternative syntax 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']) 

    其它集合操作:

    names.add('CAT') # Add an item names.remove('YHOO') # Remove an item s1 | s2 # Set union s1 & s2 # Set intersection s1 - s2 # Set difference 

    练习

    在这些练习中,你开始构建的程序是本课程剩余部分使用的主要程序之一。请在 Work/report.py 文件中工作。

    练习 2.4:包含元组的列表

    Data/portfolio.csv 文件包含投资组合中的股票列表。在 练习 1.30 中,你编写了一个读取该文件并执行简单计算的 portfolio_cost(filename) 函数。

    代码看起来应该像下面这样:

    # pcost.py import csv def portfolio_cost(filename): '''Computes the total cost (shares*price) of a portfolio file''' 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 。在 report.py 文件中,定义 read_portfolio(filename) 函数,该函数打开 Data/portfolio.csv 文件并将其读入到包含元组的列表中。为此,你需要对上面的代码做一些小修改。

    首先,创建一个最初设为空列表的变量,而不是定义 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('Data/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 >>> 

    创建的包含元组的列表非常类似于二维( 2-D)数组。例如,使用诸如 portfolio[row][column]rowcolumn 是整数)的查找来访问特定的列和行。

    也就是说,可以使用像下面这样的语句重写最后的 for 循环:

    >>> total = 0.0 >>> for name, shares, price in portfolio: total += shares*price >>> print(total) 44671.15 >>> 

    练习 2.5:包含字典的列表

    使用字典(而不是元组)修改在练习 2.4 中编写的函数来表示投资组合中的股票。在字典中,使用字段名 "name", "shares" 和 "price" 来表示输入文件中的不同列。

    以与练习 2.4 中相同的方式试验这个新的函数。

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

    练习 2.6:把字典当作容器

    在使用索引而不是数字查找某元素的地方,字典是一种用来跟踪元素的很有用的方式。在 Python shell 中,尝试使用字典:

    >>> prices = { } >>> prices['IBM'] = 92.45 >>> prices['MSFT'] = 45.12 >>> prices ... look at the result ... >>> prices['IBM'] 92.45 >>> prices['AAPL'] ... look at the result ... >>> 'AAPL' in prices False >>> 

    Data/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('Data/prices.csv', 'r') >>> rows = csv.reader(f) >>> for row in rows: print(row) ['AA', '9.22'] ['AXP', '24.85'] ... [] >>> 

    另外一个小麻烦是 Data/prices.csv 文件可能有一些空行在里面。注意上面数据的最后一行是一个空列表意味在那一行没有数据。

    这有可能导致你的程序因为异常而终止。酌情使用 tryexcept 语句捕获这些异常。思考:使用 if 语句来防范错误的数据是否会更好?

    编写完 read_prices() 函数,请交互式地测试它并确保其正常工作:

    >>> prices = read_prices('Data/prices.csv') >>> prices['IBM'] 106.28 >>> prices['MSFT'] 20.89 >>> 

    练习 2.7:看看你是否可以退休

    通过添加一些计算盈亏的语句到 report.py 程序,将所有的工作联系到一起。这些语句应该采用在练习 2.5 中存储股票名称的列表,以及在练习 2.6 中存储股票价格的字典,并计算投资组合的当前值以及盈亏。

    注:完整翻译见 https://github.com/codists/practical-python-zh

    3 条回复    2021-02-22 18:51:50 +08:00
    oakcdrom
        1
    oakcdrom  
       2021 年 2 月 22 日
    哥们,啥时候能整个根据项目来学习 python 啊,比如基于 flask 开发个博客,前后端,从头讲到尾,需要哪些模块,该怎么设计。。
    codists
        2
    codists  
    OP
       2021 年 2 月 22 日
    @oakcdrom
    1 、根据项目学习确实也是很不错的一种学习方式。但是如果根据项目同时讲解 Python, Flask, 前端等等。可能不大现实,因为所涉及的内容太多了。
    2 、你是否是想学习 flask 或者其它框架?如果是的话,可以看下《 Flask Web 开发:基于 Python 的 Web 应用开发实战》这本书。
    3 、无论学习什么,选择一个教程即可,然后静下心去学习。如果你在学习的过程中遇到问题,也可以留言,大家一起交流。
    oakcdrom
        3
    oakcdrom  
       2021 年 2 月 22 日
    @codists 前端可以不用讲,毕竟有其他的教程,就讲讲前后端怎么配合就完了,前端界面展示,后端功能实现。。差不多是这个意思,哎,我菜的狠,入门教程也是看的半瓶水,看似懂了点,又看似什么也不会。。

    我去看看这个书,谢谢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2382 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 51ms UTC 16:08 PVG 00:08 LAX 09:08 JFK 12:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86