上一节(1.7函数)|下一节(2.2容器)2.1数据类型和数据结构本节介绍以元组和字典表示的数据结构。原始数据类型Python有一些原始数据类型:IntegerFloatString(Text)Emptytypeemail_address=NoneNone通常用作可选值或缺失值的占位符。它在条件语句中的计算结果为False。ifemail_address:send_email(email_address,msg)数据结构实际程序有更复杂的数据。例如持有某只股票的信息:100股GOOG,价格为490.10这是一个包含三部分的“对象”:股票的名称或代码(“GOOG”,字符串)股票数量(100,整数)price(490.10,float)元组元组是组合在一起的值的集合。示例:s=('GOOG',100,490.1)有时在句法上会省略()。s='GOOG',100,490.1特殊情况(0元组,1元组)。t=()#空元组w=('GOOG',)#1-item元组通常用于表示简单的记录或结构。通常,它是由多个部分组成的单个对象。这里有一个很好的类比:元组就像数据库表中的一行。元组的内容是有序的(类似于数组)。s=('GOOG',100,490.1)name=s[0]#'GOOG'shares=s[1]#100price=s[2]#490.1但是元组的内容不能修改。>>>s[1]=75TypeError:objectdoesnotsupportitemassignment您可以根据当前元组创建一个新的元组。s=(s[0],75,s[2])tuplepackingtuples更多的是将相关项打包成一个实体。s=('GOOG',100,490.1)然后这个元组很容易作为单个对象传递给程序的其他部分。元组解包要在其他地方使用元组,您需要将元组的一部分解包到变量中。name,shares,price=sprint('Cost',shares*price)左边的变量个数必须和元组的结构相匹配。name,shares=s#ERRORTraceback(mostrecentcalllast):...ValueError:toomanyvaluestounpacktuplesandlists元组看起来像只读列表。但是,元组最常用于由多个部分组成的单个项目。列表通常是相同类型的项目的集合,record=('GOOG',100,490.1)#表示投资组合中记录的元组symbols=['GOOG','AAPL','IBM']#列表代表三只股票符号字典是键到值的映射。有时字典也称为哈希表或关联数组。键用作访问值的索引。s={'name':'GOOG','shares':100,'price':490.1}常用操作要从字典中获取值,请使用键名。>>>print(s['name'],s['shares'])GOOG100>>>s['price']490.10>>>要添加或修改值,请使用键名进行分配。>>>s['shares']=75>>>s['date']='6/6/2007'>>>要删除一个值,请使用del语句。>>>dels['date']>>>为什么要用字典?当有许多不同的值可能被修改或操作时,字典很有用。字典使代码更具可读性。s['price']#vss[2]练习在最后几个练习中,我编写了一个程序来获取数据文件Data/portfolio.csv。使用csv模块,很容易逐行读取文件。>>>importcsv>>>f=open('Data/portfolio.csv')>>>rows=csv.reader(f)>>>next(rows)['name','shares','price']>>>row=next(rows)>>>row['AA','100','32.20']>>>虽然读取文件很容易,但处理数据往往比读取数据更难它有很多东西。例如,您可能想要存储它并对其执行一些计算。不幸的是,原始数据“行”不会这样做。例如,甚至不是简单的数学计算。>>>row=['AA','100','32.20']>>>cost=row[1]*row[2]Traceback(最近调用最后):文件“”,第1行,inTypeError:can'tmultiplysequencebynon-intoftype'str'>>>要执行更多操作,您通常需要以某种方式解释原始数据并将其转换为更有用的对象类型,以供以后处理.有两个简单的选择:元组或字典。练习2.1:元组在交互式提示下,创建以下表示前一行的元组,但将数字列转换为适当的数字。>>>t=(row[0],int(row[1]),float(row[2]))>>>t('AA',100,32.2)>>>使用这种方式,现在你可以使用股数乘以价格计算总价>>>cost=t[1]*t[2]>>>cost3220.0000000000005>>>数学在Python中没用吗?为什么结果是3220.0000000000005?这是您计算机上浮点硬件的产物,只能准确表示二进制中的小数(不是十进制)。即使是涉及小数的简单计算也会引入小错误。这是很正常的,如果您以前没有见过它,可能会有点惊讶。虽然所有使用浮点小数的编程语言都会出现这种情况,但是在打印的时候可以隐藏起来,例如:>>>print(f'{cost:0.2f}')3220.00>>>元组被读取-仅有的。您可以通过尝试将共享数更改为75来验证这一点。>>>t[1]=75Traceback(最近一次调用最后一次):文件“”,第1行,在TypeError:'tuple'objectdoesnotsupportitemassignment>>>不能改变元组的内容,但是总是可以创建一个全新的元组来替换旧的元组。>>>t=(t[0],75,t[2])>>>t('AA',75,32.2)>>>每当像这样重新分配现有变量名称时,将抛出旧值离开。虽然上面的赋值可能看起来修改了元组,但它实际上是创建一个新的元组并丢弃旧的元组。元组常用于将值打包或解包到变量中。试试这个:>>>name,shares,price=t>>>name'AA'>>>shares75>>>price32.2>>>获取上面的变量并将它们打包回一个元组:>>>>t=(name,2*shares,price)>>>t('AA',150,32.2)>>>练习2.2:将字典视为数据结构您可以创建字典而不是元组。>>>d={'name':row[0],'shares':int(row[1]),'price':float(row[2])}>>>d{'name':'AA','shares':100,'price':32.2}>>>计算持有的总价格:>>>cost=d['shares']*d['price']>>>cost3220.0000000000005>>>将此示例与上面涉及元组的相同计算进行比较,将份额数修改为75。>>>d['shares']=75>>>d{'name':'AA','shares':75,'price':32.2}>>>与元组不同,字典可以自由修改。添加一些属性:>>>d['date']=(6,11,2007)>>>d['account']=12345>>>d{'name':'AA','shares':75,'price':32.2,'date':(6,11,2007),'account':12345}>>>练习2.3:对字典的其他操作如果将字典转换成列表,你将得到它的所有键:>>>list(d)['name','shares','price','date','account']>>>同样,如果你用for语句遍历一个字典,你会得到它的所有钥匙。>>>forkind:print('k=',k)k=namek=sharesk=pricek=datek=account>>>试试这个也执行查找的变体:>>>forkind:print(k,'=',d[k])name=AAshares=75price=32.2date=(6,11,2007)account=12345>>>也可以使用keys()方法获取所有的keys:>>>keys=d.keys()>>>keysdict_keys(['name','shares','price','date','account'])>>>这里的keys()略有不同,它返回Adict_keys对象。这是对原始字典的覆盖,它始终提供当前字典的键-即使字典发生变化。例如,试试这个操作:>>>deld['account']>>>keysdict_keys(['name','shares','price','date'])>>>注意虽然d.keys(),但关键的“帐户”不见了。一起使用键和值的一种更优雅的方法是使用items()方法。这会产生一个键值元组(key,value)。>>>items=d.items()>>>itemsdict_items([('name','AA'),('shares',75),('price',32.2),('date',(6,11,2007))])>>>fork,vind.items():print(k,'=',v)name=AAshares=75price=32.2date=(6,11,2007)>>>如果你有像项目这样的元组,你可以使用dict()函数来创建一个字典。试试这个:>>>itemsdict_items([('name','AA'),('shares',75),('price',32.2),('date',(6,11,2007))])>>>d=dict(items)>>>d{'name':'AA','shares':75,'price':32.2,'date':(6,11,2007)}>>>内容|上一节(1.7函数)|下一节(2.2容器)注意:完整翻译见https://github.com/codists/practical-python-zh