Python数据结构

简介:

前言

Python作为一种弱类型编程语言,其数据类型较之于C/C++无论是在数据的存储还是调用都有着很大的区别。其特有的字典类型更是一个非常经典且功能强大的数据类型。下面一起来学习Python的数据类型,期间也会穿插一些Python的实用技巧。

软件环境

  • 系统 
    • Ubuntukylin 14.04
  • 软件 
    • Python 4.7.6
    • IPython 4.0.0

Python数据结构树状图

  • 基本数据类型 
    • 数值型 
      – 整型 
      – 浮点型 
      – 复数
    • 布尔型
    • 字符型
  • 组合数据类型 
    • 序列 
      – 列表 
      – 元组 
      – 字符串
    • 字典
    • 集合
    • 文件
  • 自定义类型 

基本数据类型

数值型

整型Integral

整型int是一种不可变类型

In [9]: num = 1

In [10]: num = 2

In [11]: num
Out[11]: 2

需要注意的是,num = 1、 num = 2 并不是同一个数据对象。第一个num变量保存着 1 在内存中存储的索引地址,第二个变量num则表示 2 在内存中存储的索引地址。在上面的两次赋值中,1、2 两个数据对象在内存中并没有改变,改变的只是 num 变量所指向的内存地址。所以说int类型是一种不可变类型,int类型对象在内存中并不会发生改变,但可以改变int型对象所对应变量的值。其调用过程为:变量num只存储了索引地址,再通过索引找到在内存中存储的int型对象,并最终引用出来。

浮点型Float

In [51]: floatTest
Out[51]: 3.141592

In [52]: floatTest = 3.14159299999999999999999999999999999999999

In [53]: floatTest
Out[53]: 3.141593

In [54]: type(float)
float      floatTest  

上面的例子可以看出Python中float类型的数据同样有着存储限制。

复数

Python还支持复数,为Math领域的研究提供了非常好的支持。

In [48]: pulralTest = 3+6j

In [49]: pulralTest
Out[49]: (3+6j)

布尔型Bool

In [12]: bool = False

In [13]: bool
Out[13]: False 

In [15]: bool = True

In [16]: bool
Out[16]: True

布尔类型可以直接赋值,注意首字母要大写。

变量的命名规则

  1. 大小写敏感,可以含有下划线_ 。
  2. 命名惯例
    a. 尽量不要以’ _ ’ 为首字母 
    b. ‘_X_’ 为系统变量,有特殊含义 
    c. ‘__X’ 表示类的本地变量,在类中调用(注意:是两条下划线’__’) 
    d. ‘__X__’ Python Module的内置方法 
    e. ’ _ ’ 存储着当前最后一个表达式的结果
In [42]: 2*3
Out[42]: 6

In [43]: print _
6

使用dir( )函数可以显示Python一般对象的内置方法,如下:

In [58]: import platform

In [59]: dir(platform)
Out[59]: 
['DEV_NULL',
 '__builtins__',
 '__copyright__',
 '__doc__',
 '__file__',
 '__name__',
 '__package__',
 '__version__',
 '_abspath',
 '_architecture_split',
 '_bcd2str',
 '_codename_file_re',
 '_default_architecture',
 '_dist_try_harder',
 '_distributor_id_file_re',
 '_follow_symlinks',
 '_ironpython26_sys_version_parser',
 '_ironpython_sys_version_parser',
 '_java_getprop',
 '_libc_search',
 '_lsb_release_version',
 '_mac_ver_gestalt',
 '_mac_ver_lookup',
 '_mac_ver_xml',
 '_node',
 '_norm_version',
 '_parse_release_file',
 '_platform',
 '_platform_cache',
 '_popen',
 '_pypy_sys_version_parser',
 '_release_file_re',
 '_release_filename',
 '_release_version',
 '_supported_dists',
 '_sys_version',
 '_sys_version_cache',
 '_sys_version_parser',
 '_syscmd_file',
 '_syscmd_uname',
 '_syscmd_ver',
 '_uname_cache',
 '_ver_output',
 '_win32_getvalue',
 'architecture',
 'dist',
 'java_ver',
 'libc_ver',
 'linux_distribution',
 'mac_ver',
 'machine',
 'node',
 'os',
 'platform',
 'popen',
 'processor',
 'python_branch',
 'python_build',
 'python_compiler',
 'python_implementation',
 'python_revision',
 'python_version',
 'python_version_tuple',
 're',
 'release',
 'string',
 'sys',
 'system',
 'system_alias',
 'uname',
 'version',
 'win32_ver']

In [60]: dir(type)
Out[60]: 
['__abstractmethods__',
 '__base__',
 '__bases__',
 '__basicsize__',
 '__call__',
 '__class__',
 '__delattr__',
 '__dict__',
 '__dictoffset__',
 '__doc__',
 '__eq__',
 '__flags__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__instancecheck__',
 '__itemsize__',
 '__le__',
 '__lt__',
 '__module__',
 '__mro__',
 '__name__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasscheck__',
 '__subclasses__',
 '__subclasshook__',
 '__weakrefoffset__',
 'mro']

而Module或函数的__doc__方法可以显示Module或函数的Document,以此来认识一个Module或函数。而这些Document,写入在Python Module文件首部的三引号中”’ “’,同时”’ ”’作为批量输出的标识,用于同时输出多行内容或充当注释。

In [64]: platform.__doc__
Out[64]: ' This module tries to retrieve as much platform-identifying data as\n    possible. It makes this information available via function APIs.\n\n    If called from the command line, it prints the platform\n    information concatenated as single string to stdout. The output\n    format is useable as part of a filename.\n\n'

In [65]: id.__doc__
Out[65]: "id(object) -> integer\n\nReturn the identity of an object.  This is guaranteed to be unique among\nsimultaneously existing objects.  (Hint: it's the object's memory address.)"

组合数据类型

序列

Python最基本的组合数据结构就是序列。序列,即由非负整数索引的对象的有序集合。有下列6种内建序列类型,其中又可以归为3类: 
1. 整数序列:xrange对象 
2. 字符序列:字符串、buffer(缓冲区)对象、Unicode字符串 
3. 对象序列:列表、元组 
其中列表、元组、字符串都是Python程序中非常常用的两种类型。

字符串String

字符串是一种序列,可以通过索引引用,以字符为单位,属于不可变类型。当定义一个str对象时,str对象会在内存中以ASCII码的格式从索引对象指定的入口地址依次以字符为单位存放起来,其中每一个Char都占用1Byte(8bit)的存储空间。 
:在Python中的字符串可以使用 ‘Str’ 或者 “Str” 括起来,而且两者没有任何的区别,只视乎于那一个使用起来更加方便和更适合使用环境。随便一提’” Document ‘”在Python中表示文档,用在代码行中,有类似注释的功能,而且’” ‘”中可以使用单引号和双引号。 
例子(1).

In [19]: name = 'jmilk'

In [20]: id(name)
Out[20]: 140682798476624

In [21]: name = 'chocolate'

In [22]: id(name)
Out[22]: 140682799006128

In [23]: type(name)
Out[23]: str

例子(2).

In [36]: name1 = 'jmilk'

In [37]: name2 = 'jmilk'

In [39]: id(name1) == id(name2)
Out[39]: True

id(variable):查询变量存储的索引地址 
type(variable):查看变量的数据类型 
例子(1)中,显然同一个name变量在赋与不同的字符串类型值后name变量自身的索引地址发生了改变。 
例子(2)中,将同一个str对象’jmilk‘赋值给两个不同的变量,这两个变量的值(内存中的引用对象)却是一样的。 
字符串的切片: 
字符串最为序列的一种,可以使用切片操作符来实现字符串的切片显示。

In [62]: sentence = 'my name is jmilk'

In [63]: sentence
Out[63]: 'my name is jmilk'

(1)stringName[x:y] –>显示字符串中从第x个索引的字符–第y-1个字符,索引从0开始计算,其中的空格也算一个字符。

In [64]: sentence[0:7]
Out[64]: 'my name'

(2)当x或y为空时,默认为显示往前、往后的所有

In [66]: sentence[:7]
Out[66]: 'my name'

In [68]: sentence[7:]
Out[68]: ' is jmilk'

(3)string[x:y:步进],在上述的基础上加入步进显示

In [70]: sentence[0:7]
Out[70]: 'my name'

In [71]: sentence[0:7:3]
Out[71]: 'mne'

In [72]: sentence[0:7:2]
Out[72]: 'm ae'

从例子(3)中可以看出,步进的作用即将切片后的字符串,从第一次字符开始,往后均已以步进指定的间隔取出字符。

小结:当执行一条赋值语句时,生成了两个内存对象。分别如下: 
1). 数据对象:Python会将所有的数据对象存放到分配的存储中(一般存放在内存中特定的地址块)。 
2). 引用对象:既是变量,其在内存中存放指定的数据对象的索引地址,既数据对象和变量是分别存放的。程序运行时,通过引用对象(变量)来调用出数据对象的值。而且引用对象(变量)是动态类型,可以任意改变引用对象的索引值。 
值得注意的是,Python自身带有垃圾回收的机制,各种对象在不被引用的时候,便自动由垃圾回收器回收。如上述例子(1),在str对象’jmilk‘不被任何引用对象指向时,会被系统回收掉其资源。

元组Tuple

元组是不可变对象,使用tupleName = (parameters)创建。

In [3]: number = ('one','two','three')

In [4]: number
Out[4]: ('one', 'two', 'three')

In [5]: type(number)
Out[5]: tuple

In [6]: id(number)
Out[6]: 139715119475680

In [7]: number = ('one','two','four')

In [8]: id(number)
Out[8]: 139715119475360

使用id( )方法,显然两个number引用对象的索引是不一致的。而且在定义tuple对象后,就可以使用tuple对像的一些内置方法: 
首先使用dir( )来获取tuple类型对象number的多有内置方法

In [9]: dir(number)
Out[9]: 
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__getnewargs__',
 '__getslice__',
 '__gt__',
 '__hash__',
 '__init__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmul__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'count',
 'index']

或者也可以使用内置函数help(Object)来获取一个对象详细的帮助文档

In [25]: help(number)

会得到所有对象内置函数的使用格式和方法,如下:

Help on tuple object:

class tuple(object)
 |  tuple() -> empty tuple
 |  tuple(iterable) -> tuple initialized from iterable's items
 |  
 |  If the argument is a tuple, the return value is the same object.
 |  
 |  Methods defined here:
 |  
 |  __add__(...)
 |      x.__add__(y) <==> x+y
 |  
 |  __contains__(...)
 |      x.__contains__(y) <==> y in x
 |  
 |  __eq__(...)
 |      x.__eq__(y) <==> x==y
 |  
 |  __ge__(...)
 |      x.__ge__(y) <==> x>=y
 |  
 |  __getattribute__(...)

例如可以使用__add__方法来连接两个tuple对象

In [32]: name = ('jmilk','chocolate')

In [33]: number.__add__(name)
Out[33]: ('one', 'two', 'four', 'jmilk', 'chocolate')

使用__eq__来判断两个tuple对象是否一致

In [42]: name.__eq__(number)
Out[42]: False

使用__contains__来判断tuple对象是否包含一个元素

In [44]: number.__contains__('one')
Out[44]: True

总而言之,善于使用help( )、doc()、__doc__等方法可以很好的帮助我们更加充分的认识Python这门语言,也可以非常的便于我们程序的编写。

列表List

列表是可变对象,使用ListName = [Parameters]创建。是任意对象的有序集合,通过索引访问其中的元素,可以任意的嵌套、伸长、异构(不同的数据类型,同时存放在一个List中,支持原处修改内部元素的引用。如果说元组类似于一元数组,那列表就相当于二元数组的效果。

In [41]: testListOne = [1,2,3]

In [42]: id(testListOne)
Out[42]: 139682261309632

In [45]: testListTwo = testListOne

In [43]: testListOne.append(4)

In [47]: testListOne
Out[47]: [1, 2, 3, 4]

In [48]: id(testListOne),id(testListTwo)
Out[48]: (139682261309632, 139682261309632)

从上面的例子可以看出,即便在testListOne对象中插入元素’4’后,testListOne与testListTwo的地址仍然是一致的,即在改变testListOne对象的值后,没有创建出一个新的内存对象,这是有别于不可变对象的。 
值得注意的是,只有使用了List类型对象内置的append、extend、remove、insert等方法的时候才会在原有的内存对象的基础上作出修改。不可以直接使用下述的方法来直接修改一个List对象的value。

In [53]: testListOne = [1,2,3,4,5,6]

In [54]: id(testListOne),id(testListTwo)
Out[54]: (139682261332696, 139682261309632)

直接修改List对象的Value,会产生一个新的内存对象。 
:List类型的对象本质是在列表变量的引用对象指向的地址空间中存放了列表中的元素的存储索引地址。而这种可以包含其他对象的引用的对象也称为容器。所以List类型虽然是可变的,但是List的元素本身不一定是可变的。因为List作为一个组合数据类型对象其可以实现对象的嵌套,List中的元素可以是string、tuple等不可变的类型,也可以是dic、list等可变类型的嵌套。

小结
1. 不可变对象:int、float、string、tuple 对一个不可变类型的变量赋以新的值,会改变变量引用对象的索引值,使引用对象新的索引指向新的内存对象。原有的内存对象不会发生改变,但若不再被引用对象引用时,会自动的被垃圾回收机制回收。 
2. 可变对象:list、distionary 对一个可变类型的变量赋以新的值,会直接在变量引用对象指向的内存空间中存放新的value,而不会重新开辟新的空间存放新的值。

字典dictionary

字典是Python特有的一种数据结构,其不是以下标的索引来查询数据,而是使用Key:Value的键值对来实现变量和数据的映射,所以字典也被称之为映射数据类型。字典使用dictName = {key1:vlalue1,key2:value2,…}创建。字典数据类型,使得Python程序具有了更好的灵活性,因为其键值对的设计,很好的兼用了JOSN、NoSQL等主流数据处理技术。 
创建一个字典:

In [2]: dictName = {'fan':'jmilk','zhang':'san','li':'si'}

In [3]: dictName
Out[3]: {'fan': 'jmilk', 'li': 'si', 'zhang': 'san'}

显示字典中的元素:

In [17]: dictName['fan']
Out[17]: 'jmilk'

In [19]: dictName['fan'],dictName['zhang'],dictName['li']
Out[19]: ('jmilk', 'san', 'si')

分别显示字典中的keys或values

In [30]: dictName.keys()
Out[30]: ['li', 'fan', 'zhang']

In [31]: dictName.values()
Out[31]: ['si', 'jmilk', 'san']

在字典中加入key:value

In [33]: dictName['wang'] = 'wu'

In [36]: dictName
Out[36]: {'fan': 'jmilk', 'li': 'si', 'wang': 'wu', 'zhang': 'san'}

将字典中的一对key:value弹出(删除)

In [50]: dictName.pop('fan')
Out[50]: 'jmilk'

In [51]: dictName
Out[51]: {'li': 'si', 'wang': 'wu', 'zhang': 'san'}

当然,字典类型的对象还有许多使用的内置方法,建议使用help(dictName)取详细的了解一个字典类型的对象所能实现的功能。

最后

掌握Python数据结构是编写Python程序的基本要求,当然Pyehon的数据结构的内容远比上述的要丰富许多。在以后的博文中我们更加详细 
深入的去学习每一个数据类型的具体实现和功能。 
Jmilk

目录
相关文章
|
1天前
|
机器学习/深度学习 算法 Python
数据分享|Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户
数据分享|Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户
14 4
|
1天前
|
机器学习/深度学习 算法 算法框架/工具
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
15 0
|
1天前
|
机器学习/深度学习 数据挖掘 网络架构
Python对商店数据进行lstm和xgboost销售量时间序列建模预测分析
Python对商店数据进行lstm和xgboost销售量时间序列建模预测分析
|
1天前
|
数据挖掘 数据处理 索引
如何使用Python的Pandas库进行数据筛选和过滤?
Pandas是Python数据分析的核心库,提供DataFrame数据结构。基本步骤包括导入库、创建DataFrame及进行数据筛选。示例代码展示了如何通过布尔索引、`query()`和`loc[]`方法筛选`Age`大于19的记录。
9 0
|
2天前
|
机器学习/深度学习 算法 数据挖掘
PYTHON银行机器学习:回归、随机森林、KNN近邻、决策树、高斯朴素贝叶斯、支持向量机SVM分析营销活动数据|数据分享-2
PYTHON银行机器学习:回归、随机森林、KNN近邻、决策树、高斯朴素贝叶斯、支持向量机SVM分析营销活动数据|数据分享
21 1
|
2天前
|
数据处理 Python
如何使用Python的Pandas库进行数据排序和排名
【4月更文挑战第22天】Pandas Python库提供数据排序和排名功能。使用`sort_values()`按列进行升序或降序排序,如`df.sort_values(by=&#39;A&#39;, ascending=False)`。`rank()`函数用于计算排名,如`df[&#39;A&#39;].rank(ascending=False)`。多列操作可传入列名列表,如`df.sort_values(by=[&#39;A&#39;, &#39;B&#39;], ascending=[True, False])`和分别对&#39;A&#39;、&#39;B&#39;列排名。
13 2
|
3天前
|
Python
如何使用Python的Pandas库进行数据缺失值处理?
Pandas在Python中提供多种处理缺失值的方法:1) 使用`isnull()`检查;2) `dropna()`删除含缺失值的行或列;3) `fillna()`用常数、前后值填充;4) `interpolate()`进行插值填充。根据需求选择合适的方法处理数据缺失。
34 9
|
5天前
|
索引 Python
如何使用Python的Pandas库进行数据透视表(pivot table)操作?
使用Pandas在Python中创建数据透视表的步骤包括:安装Pandas库,导入它,创建或读取数据(如DataFrame),使用`pd.pivot_table()`指定数据框、行索引、列索引和值,计算聚合函数(如平均分),并可打印或保存结果到文件。这允许对数据进行高效汇总和分析。
10 2
|
6天前
|
JSON 关系型数据库 数据库
《Python 简易速速上手小册》第6章:Python 文件和数据持久化(2024 最新版)
《Python 简易速速上手小册》第6章:Python 文件和数据持久化(2024 最新版)
33 0
|
7天前
|
机器学习/深度学习 Python 数据处理
Python中利用长短期记忆模型LSTM进行时间序列预测分析 - 预测电力负荷数据
Python中利用长短期记忆模型LSTM进行时间序列预测分析 - 预测电力负荷数据
30 0
Python中利用长短期记忆模型LSTM进行时间序列预测分析 - 预测电力负荷数据