python基础教程笔记(chapt.2&4) 数据结构

数据结构

通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其他数据结构

容器(container)

包含其他对象的任意对象。序列(例如列表和元组)和映射(字典)是两类主要容器

序列(sequence)

索引: 每个元素被分配的号,即元素的位置。每个元素都有自己的编号

>>>edward=['Edward Gumby', 42
>>>john=['John Smith', 50]
>>>database=[edward, john]
>>>database
[['Edward Gumby', 42],['John Smith', 50]]
  1. 索引(indexing)
    正数从0开始, 倒数-1开始,字符串可以直接索引
>>>greeting='Hello'
>>>greeting[0]
'H'
>>>greeting[-1]
'o'
>>>'Hello'[1]
'e'

取用户输入的年份第4位

>>>fourth=raw_input('Year: ')[3]
Year:  2005
>>>fourth
'5'

练习: 要求输入年,月,日,打印相应日期连续格式,月份按单词。

#-*- coding:utf-8 –*-
# 根据给定的年月日打印相应的日期的月份名称
months=['January', 'February', 'March','April', 'June', 'July','August', 'September', 'October', 'November', 'December']
# 以1-31的数字作为结尾的列表
endings=['st','nd','rd']+ 17*['th']+['st','nd','rd']+7*['th']+['st']

year=raw_input('Year: ')
month=raw_input('Month (1-12): ')
day=raw_input('day(1-31) ')

month_number=int(month)
day_number=int(day)

#月份,日期减1,获得正确索引
month_name=months[month_number-1]
original=day+endings[day_number-1]

print month_name+' '+ original+' '+year
  1. 分片(sliceing)[起:终:步长]
    分片操作需要提供两个索引作为便捷,第一个元素包含在分片内,第二个不包含。
    10个数,1,2,3,4,5,6,7,8,9,10
    取全部:[:] 1,2,3,4,5,6,7,8,9,10
    取索引至5(不包括5):[:5] 1,2,3,4,5
    取索引6起(包括6)后所有:[5:] 6,7,8,9,10
    取索引6起(包括6)后所有(已知索引最后位才可用,索引为10的数不存在,不过也不用取,所以不影响):[5:10] 6,7,8,9,10
    取索引1起至索引3(不包括3):[1:3] 1,2,3
    取倒数第3个至第一个[-3, -1]:
    步长不能为0,可以为负数。负数时表示从右往左提取,索引也反过来写
    索引为8的至索引为3的[8:3:-1] : 9,7,6,5

  2. 加(adding)

  • 相同类型的序列,直接用+相加,变成一个序列
  • 不相同类型的序列,不能相加
  1. 乘(multiplying)
    用数字x乘一个序列,序列会生成一个将原来序列重复N次的新序列
    常用初始化列表:
    >>>sequence=[None]*10

练习: 其中书是box_width-2,我跑了发现不对,改成4.

#-*- coding:utf8 -*-
#以正确的宽度在居中的盒子内打印一句话
#注意,正数除法运算符//只能用在python 2.2以后版本,之前版本,只能用普通除法

sentence=raw_input("Sentence: ")
screen_width=80
text_width=len(sentence)
box_width=text_width+6
left_margin=(screen_width-box_width)//2

print
print ' '* left_margin+'+' +'-'* (box_width-4)+ '+'
print ' '* left_margin+'| '+' '* text_width   + ' |'
print ' '* left_margin+'| '+    sentence      + ' |'
print ' '* left_margin+'| '+' '* text_width   + ' |'
print ' '* left_margin+'+' +'-'* (box_width-4)+ '+'
print

  1. 检查某个元素是否属于序列成员(查看权限,提供的用户名是否存在等安全策略, 垃圾邮箱过滤)
    '信息' in 序列名
    得到的结果是布尔值
>>>raw_input('Enter your user name: ') in users
Enter your user name:m1h
True

练习: 检查用户名和密码是否匹配

#-*- coding:utf8 -*-
#检查用户名和密码
database=[['albert', '1234'], ['dilbert','4242'],['smith','7524'],['jones','9843']]
username=raw_input('User name: ')
pin=raw_input('Pin code: ')

if[username, pin] in database: print 'Access granted'
  1. 计算序列长度
    len(序列x)
  2. 找到最大元素
    max(序列x)
  3. 最小元素
    min(序列x)
  4. 迭代
1. 列表list

可修改(mutable).
创建: x=[列表内容] 创建字符串列表可以直接 list('字符串') 会生成一个一个字符单个作为一个元素的列表。
' '.join(somelist)
修改: x[要修改的元素索引位置]=修改目标值
删除: del x[要删除的索引位置],会将列表变小。
分片赋值: 通过分片赋值可以达到批量修改(不局限列表长度),批量插入新元素(x[1:1]=[插入内容]), 删除元素(x[2:4]=[])
--------列表的方法:----
对象.方法(参数)

  1. append(元素) 在列表最末尾加上新元素,改变原list
  2. count(元素) 统计某个元素出现次数,返回次数
  3. extend(元素) 在列表末尾追加另一个序列的多个值,改变原list
  4. index(元素), 找到该元素的索引, 返回索引
  5. insert(要插入位置的索引, 要插入的元素):插入元素到目标索引,改变原list
  6. pop(为空是移除最后一个,或者填要移除的索引):移除list中最后一个或者索引对应元素,返回该被移除的元素,改变原list
    数据结构:栈 (入栈,出栈)
    用append()+pop()实现LIFO后进先出的队列
    用insert(0,...)+pop()或者pop(0)+append()或者collection.deque实现FIFO先进先出队列
  7. remove(元素):移除第一个匹配项,无返回值,改变原list
    8.reverse(空): 将列表中的元素反过来存放,改变原list,返回的是一个迭代器对应
    9.sort(cmp, key, reverse):将列表排序。改变原list,返回值为None。key是依照排序的对象,比如按照元素长度排序,就key=len,reverse为布尔值,是否反响排序,填True 或者False.cmp同compare
    sorted(x):将列表排序,不改变原list,输出排序后的list,故而如需保存需要赋值。该函数可用于任何可迭代对象
    10.compare(x,y):高级排序,当x<y时,返回负数,x>y时,返回正数,x=y则返回0
x.sort().reverse() 不可行,因为sort()返回值为None
sorted(x).reverse() 可行
排序拓展
2. 元组tuple

不可修改
创建:(x,); x,; tuple()

映射

映射可以使用任何不可变对象标识元素,常见类型是字符串和元组,python唯一的内建映射就是字典。
键: 每个元素都有自己的名字,唯一

1.字典

适用于: 象征游戏棋盘的状态,每个键都是由坐标值组成的元组;存储文件修改次数,用文件名作为键;数字电话/地址簿
创建:{}; dict([(键),(值)]); dict(键名=键, 值名=值)
查看键-值数量:len(字典)
查值: 字典名[键]
关联(赋值): 字典[键]=值
删除某键及对应值: del 字典[键]
检查是否存在: 键 in 字典

练习 书里少了一行关于request定义。

#-*- coding=utf8 -*-
#简单数据库
#使用人名作为键的字典,每个人用另一个字典来表示,其键'phone'和'addr'分别表示他们的电话号码和地址
people={'Alice':{'phone':'2341','addr':'Foo drive 23'}, 'Beth':{'phone':'9102','addr':'Bar street 42'},
        'Ceil':{'phone':'3158','addr':'Baz avenue 90'}}
#针对电话号码和地址是用的描述性标签,会在打印输出的时候用到
label={'phone':'phone number','addr':"address"}

name=raw_input('Name: ')
request=raw_input('Phone number(p) or address (a)?')

#查找电话号码还是地址? 使用正确的键
#使用正确的键
if request == 'p':key='phone'
if request == 'a':key="addr"

#如果姓名是字典中的有效键才打印
if name in people: print "%s's %s is %s" % (name,label[key],people[name][key])

方法:

  1. clear(为空): 清空字典,和sort一样,改变原字典,不返回值(或者说返回值为None)
  2. copy(为空):返回一个相同键-值的新字典,属于浅复制,大概就是在副本中替换值(比如用赋值),原始字典不受影响,但是如果在副本当中进行了修改(比如删除了某个值),原始字典里的也会进行同样的操作。
    深复制: copy.deepcopy
>>>from copy import deepcopy
>>>d={}
>>>d['names']=['Alfred','Bertrand']
>>>c=d.copy()
>>>dc=deepcopy(d)
>>>d['names].append('Clive')
>>>c
{'names':['Alfred','Bertrand','Clive;]}
>>>d
{'names':['Alfred','Bertrand'}
  1. fromkeys(键列表,自定义默认值): 建立以提供的键列表为基础自定义默认值(不填就是None)的字典,返回创建字典。{}.fromkeys(['names'.'age']);dict.fromkeys(['names'.'age'],'(unknown)')
  2. get(键,自定义键不存在时返回啥):访问字典项, 键不存在返回自定义的值(不填返回None),存在返回值。
    练习 基于上面简单数据库加入get的应用,和格式化一起用,真的很方便,少打一万行字,深切感受到格式化的强大。这人怎么就这么聪明呢。
#-*- coding=utf8 -*-
#使用get()的简单数据库
#使用人名作为键的字典,每个人用另一个字典来表示,其键'phone'和'addr'分别表示他们的电话号码和地址
people={'Alice':{'phone':'2341','addr':'Foo drive 23'}, 'Beth':{'phone':'9102','addr':'Bar street 42'},
        'Ceil':{'phone':'3158','addr':'Baz avenue 90'}}
#针对电话号码和地址是用的描述性标签,会在打印输出的时候用到
labels={'phone':'phone number','addr':"address"}

name=raw_input('Name: ')

#查找电话号码还是地址?
request=raw_input('Phone number(p) or address (a)?')
#使用正确的键
key=request #如果请求既不是p也不是a
if request == 'p':key='phone'
if request == 'a':key="addr"

#使用get()提供默认值
label=labels.get(key,key)
person=people.get(name,{})
result=person.get(key,'not available')
#如果姓名是字典中的有效键才打印
print "%s's %s is %s" % (name,label,result)
  1. has_key(键):检查是否有这个键,返回布尔值。3.0版没有这个函数!!!和 k in d一样的功能。
  2. items(为空)和iteritmes(为空):前者将字典以[(键,值),(键,值),(键,值)]的列表形式返回,无特殊顺序。后者作用一样,不过返回的是迭代器对象。
  3. keys和iterkeys:和上面一样,前后者区别也一样,不过是只显示键。
    8.vales()和itervalues():和上面一样,前后者区别也一样,不过是只显示值。
  4. pop(键): 删除对应键-值,并且返回该键-值。
    10.popitem(为空): 随机删除字典中的一项,在想实现不用获取键列表的前提下,一个个地移除并处理项时很实用。
    11.setdefault(键盘,自定义默认值):在键存在时,返回键对应的目前值,键不存在时,增加键,并设定为默认值,默认值不填时默认None。
  5. update(更新内容字典): 用更新内容字典更新对象字典,新建会添加,相同建会覆盖对象字典原有值。

集合(set)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容