关于python:翻译实用的Python编程0201Datatypes

35次阅读

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

目录 | 上一节 (1.7 函数) | 下一节 (2.2 容器)

2.1 数据类型和数据结构

本节以元组和字典为代表介绍数据结构。

原始数据类型

Python 有一些原始数据类型:

  • 整数
  • 浮点数
  • 字符串(文本)

空类型

email_address = None

None 罕用作可选值或缺失值的占位符。它在条件语句中计算为 False

if email_address:
    send_email(email_address, msg)

数据结构

理论的程序具备更简单的数据。例如,对于股票的持有信息:

100 shares of GOOG at $490.10

这是一个蕴含三个局部的“对象”:

  • 股票的名称或符号(”GOOG”,字符串)
  • 股份数目(100,整数)
  • 价格(490.10,浮点数)

元组

元组是分组在一起的值的汇合。

示例:

s = ('GOOG', 100, 490.1)

有时候会在语法上省略 ()

s = 'GOOG', 100, 490.1

非凡状况(0 元组,1 元组)。

t = ()            # An empty tuple
w = ('GOOG',)    # A 1-item tuple

元组个别用来示意简略的记录或构造。

通常,它是由多个局部组成的单个对象。这有一个很好的类比:元组就像数据库表中的一行。

元组的内容是有序的(相似于数组)。

s = ('GOOG', 100, 490.1)
name = s[0]                 # 'GOOG'
shares = s[1]               # 100
price = s[2]                # 490.1

然而,元组的内容无奈批改。

>>> s[1] = 75
TypeError: object does not support item assignment

你能够基于以后元组创立一个新元组。

s = (s[0], 75, s[2])

元组打包

元组更多的是把相干的项打包到一个实体(entity)中。

s = ('GOOG', 100, 490.1)

而后,该元组很容易作为单个对象传递给程序的其它局部。

元组拆包

要在其它中央应用元组,能够把元组的各部分拆包为变量。

name, shares, price = s
print('Cost', shares * price)

左侧变量的数目必须与元组的构造匹配。

name, shares = s     # ERROR
Traceback (most recent call last):
...
ValueError: too many values to unpack

元组与列表

元组看起来像只读列表。然而,元组最罕用于由多个局部组成的单项。列表通常是类型雷同的项的汇合,

record = ('GOOG', 100, 490.1)       # A tuple representing a record in a portfolio

symbols = ['GOOG', 'AAPL', 'IBM']  # A List representing three stock symbols

字典

字典是键到值的映射。有时,字典也称为哈希表(hash table)或关联数组(associative array)。键用作拜访值的索引。

s = {
    'name': 'GOOG',
    'shares': 100,
    'price': 490.1
}

常见操作

要从字典中获取值,请应用键名。

>>> print(s['name'], s['shares'])
GOOG 100
>>> s['price']
490.10
>>>

要增加或批改值,请应用键名进行调配。

>>> s['shares'] = 75
>>> s['date'] = '6/6/2007'
>>>

要删除值,请应用 del 语句。

>>> del s['date']
>>>

为什么应用字典?

当存在很多不同的值并且可能会批改或操作这些值时,字典很有用。字典使代码更具可读性。

s['price']
# vs
s[2]

练习

在上次的几个练习中,编写了一个取数据文件 Data/portfolio.csv 的程序。应用 csv 模块,能够轻松地逐行读取文件。

>>> import csv
>>> 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 (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type'str'
>>>

要执行更多的操作,通常须要以某种形式解释原始数据,并将其转换为更有用的对象类型,以便当前解决。有两种简略的形式能够抉择:元组或者字典。

练习 2.1:元组

在交互式提示符下,创立以下代表上一行的元组,但数字列要转换为失当的数字。

>>> t = (row[0], int(row[1]), float(row[2]))
>>> t
('AA', 100, 32.2)
>>>

应用这种形式,当初能够应用股份数目乘以价格来计算总价,

>>> cost = t[1] * t[2]
>>> cost
3220.0000000000005
>>>

在 Python 中,数学没用了吗?后果为什么是 3220.0000000000005?

这是计算机上浮点硬件的产物,只能在二进制(而不是十进制)中精确示意小数。即便是波及十进制小数的简略计算,也会引入小的误差。这很失常,如果你之前没有见过,可能会有点诧异。

尽管在所有应用浮点小数的编程语言中都会产生这种状况,然而打印的时候能够把它暗藏,例如:

>>> print(f'{cost:0.2f}')
3220.00
>>>

元组是只读的。能够通过尝试把股份数目改为 75 来验证这点。

>>> t[1] = 75
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>

只管无奈更改元组的内容,然而始终能够创立一个全新的元组来替换旧的元组。

>>> t = (t[0], 75, t[2])
>>> t
('AA', 75, 32.2)
>>>

每当像这样重新分配现有变量名时,旧值就会被抛弃。尽管下面的赋值可能看起来像在批改元组,但实际上是在创立一个新的元组,并且将旧的元组抛弃。

元组通常用于将值打包或拆包到变量中。请尝试以下操作:

>>> name, shares, price = t
>>> name
'AA'
>>> shares
75
>>> price
32.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']
>>> cost
3220.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 语句对字典进行迭代,则将取得其所有的键。

>>> for k in d:
        print('k =', k)

k = name
k = shares
k = price
k = date
k = account
>>>

尝试应用这个同时执行查找的变体:

>>> for k in d:
        print(k, '=', d[k])

name = AA
shares = 75
price = 32.2
date = (6, 11, 2007)
account = 12345
>>>

也能够应用 keys() 办法取得所有的键:

>>> keys = d.keys()
>>> keys
dict_keys(['name', 'shares', 'price', 'date', 'account'])
>>>

在这里,keys() 略微有点不同,它返回的是一个 dict_keys 对象。

这是对原始字典的笼罩,它始终提供以后字典的键——即便字典扭转了。例如,试试一下操作:

>>> del d['account']
>>> keys
dict_keys(['name', 'shares', 'price', 'date'])
>>>

请留神,只管没有再次调用 d.keys(),但键 'account' 隐没了。

一个更优雅地一起应用键和值的形式是应用 items() 办法。这能够取得键值组成的元组 (key, value)

>>> items = d.items()
>>> items
dict_items([('name', 'AA'), ('shares', 75), ('price', 32.2), ('date', (6, 11, 2007))])
>>> for k, v in d.items():
        print(k, '=', v)

name = AA
shares = 75
price = 32.2
date = (6, 11, 2007)
>>>

如果有相似于 items 的元组,那么能够应用 dict() 函数创立一个字典。请尝试以下操作:

>>> items
dict_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

正文完
 0