Python基础数据结构的N种用法

Python提供的四种基础数据结构:list,tuple,set和dict。本文主要围绕这几种数据结构,介绍它们的各种用法。

用法一:解压序列和赋值
In [1]: employee = ['Kenny', 'Software Engineer', 30]

In [2]: name, title, age = employee

In [3]: name
Out[3]: 'Kenny'

In [4]: title
Out[4]: 'Software Engineer'

In [5]: age
Out[5]: 30

# 解压字符串
In [6]: h,e,l,l,o = 'hello'

In [7]: h                  
Out[7]: 'h'                

In [8]: e                  
Out[8]: 'e'

# 部分解压
In [12]: name,_,_ = employee

In [13]: name
Out[13]: 'Kenny'

# 通过*号匹配多个值。如果*变量位于最末,那匹配到的也是一个list,即使这个list里面没有任何元素
In [20]: *begin, nine, ten = nums 

In [21]: begin                    
Out[21]: [1, 2, 3, 4, 5, 6, 7, 8] 

In [22]: nine                     
Out[22]: 9                        

In [23]: ten                      
Out[23]: 10                       

# 一个例子
In [27]: htmltags = [('url', 'www.baidu.com', 'www.sina.com.cn', 'www.zhihu.com'),
    ...: ('img','~/pics/a.png'),
    ...: ('p','段落1','段落2', '段落3', '段落4')]

In [28]: for tag, *content in htmltags:
    ...:     if tag == 'url':
    ...:         print('urls: ', *content)
    ...:     else:
    ...:         print('rest')
    ...:
urls:  www.baidu.com www.sina.com.cn www.zhihu.com
rest
rest
用法二:可变长的参数列表
  • 参数传递:如果函数的参数列表中,包含多个参数。我们可以使用一个列表来承载,传递的时候,在这个列表前方加上一个。如果使用一个字典来承载,那么则需要两个*。
  • 定义冗余参数(可变参数列表): 参数列表的最后两个参数,可以通过列表和字典来接收。

# 参数传递
In [21]: def calc_price(unit = 100, unitprice = 0.5):                                            
    ...:     print("%d斤大白菜,单价%.2f元,总价是%.2f元。"  % (unit, unitprice, unit*unitprice))              

In [22]: calc_price()                                                                       
100斤大白菜,单价0.50元,总价是50.00元。                                                     

In [23]: unit_price = [200, 0.3]                                                                 
In [24]: calc_price(*unit_price)                                                            
200斤大白菜,单价0.30元,总价是60.00元。                                                         

In [25]: unit_price = {'unit':300, 'unitprice':0.3}
In [26]: calc_price(**unit_price)
300斤大白菜,单价0.30元,总价是90.00元。

# 定义冗余参数
In [33]: def func(a,b,*args):
    ...:     print('a = ', a)
    ...:     print('b = ', b)
    ...:     if len(args) > 0:
    ...:         print('args = ', args)
    ...:

In [34]: func(1,2)
a =  1
b =  2

In [35]: func(1,2,3,4,5,6)
a =  1
b =  2
args =  (3, 4, 5, 6)

In [36]: def func(a,b,*args, **kv):
    ...:     print('a = ', a)
    ...:     print('b = ', b)
    ...:     if len(args) > 0:
    ...:         print('args = ', args)
    ...:     for k in kv:
    ...:         print('key = %s, value = %s'% (k, kv[k]))

In [37]: func(1,2,3,4,5, name = 'xxx', age = 12)
a =  1
b =  2
args =  (3, 4, 5)
key = name, value = xxx
key = age, value = 12

用法三:切片操作

列表的索引与数组一样,也是从0开始到length-1结束。python中,列表的元素的索引可以是正序也可以是逆序。如下表所示:

h e l l o w o r l d
0 1 2 3 4 5 6 7 8 9 10
-11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1

我们可以通过下标取出特定的某个元素,也可以通过切片操作从列表中取出一部分元素。切片的语法为:alist[start:end:step],其中:

  • start:从下标start开始取,并且包括下标为start的这个元素。如果不指定start,则表示从头,也就是第一个元素开始。
  • end:到下标end结束,但不包括下标为end的这个元素。如果不指定end,则表示取到最后一个,并且包括最后一个元素。
  • step:每隔step个元素进行取值,默认为1。
# 取单一的元素
In [35]: helloworld = 'hello world'

In [36]: helloworld[10]            
Out[36]: 'd'                       

In [37]: helloworld[-1]            
Out[37]: 'd'         

# 从起始位置开始取
In [43]: helloworld[:5]
Out[43]: 'hello'

In [44]: helloworld[:-5]
Out[44]: 'hello '

# 从某个位置到末尾
In [45]: helloworld[6:]
Out[45]: 'world'

In [46]: helloworld[-5:]
Out[46]: 'world'

# 取某个区间的值
In [47]: helloworld[6:10] 
Out[47]: 'worl'           

# 设置取值的跨度
In [49]: helloworld[::2]
Out[49]: 'hlowrd'

In [50]: helloworld[::3]
Out[50]: 'hlwl'

用法四:遍历

任何一种迭代器,都是可以通过for...in...来遍历。此外,还可以通过next()和StopIteration异常来手动遍历迭代器


In [53]: for char in helloworld:
    ...:     print(char)

In [54]: for index in range(len(helloworld)):
    ...:     print(helloworld[index])

In [58]: adict = {"五香牛肉粉":13, "红烧牛肉粉":13, "什锦粉":16, "卤鸡腿粉":15}

In [59]: for key in adict:
    ...:     print(adict[key])

# 手动遍历
In [69]: myiter = iter(helloworld)

In [70]: while True:
    ...:     try:
    ...:         char = next(myiter)
    ...:         print(char)
    ...:     except StopIteration:
    ...:         break
    ...:

# 反向遍历
In [71]: for char in reversed(helloworld):
    ...:     print(char)

用法五:推导式(表达式)和生成器

推导式:实际上是一种便捷的遍历语法,最终的结果还是一个列表

  • [expr for iter_var in iterable]
  • [expr for iter_var in iterable if cond_expr]

# 例:对整数列表里的每个元素平方操作
In [72]: [x**2 for x in range(1,11)]
Out[72]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# 例:求偶数
In [73]: [x for x in range(1,11) if x%2 == 0]
Out[73]: [2, 4, 6, 8, 10]

# 例:求100以内的质数(除了能被1和自己整除外,就没有别的因数)
# if后面跟着一个判断式,如果后面的变量是None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()时,这个判断式的结果是False;所以加上not就相当于取反,那就是True
In [87]: [x for x in range(2,100) if not [j for j in range(2,x) if x % j ==0 ]]

生成器:是一种特殊的迭代器,可以通过便捷语法和生成器函数(yield)来创建。生成器的结果,顾名思义就是一个生成器。与迭代器类似,可以通过for...in...或者next()/StopIteration来遍历
便捷语法:

  • (expr for iter_var in iterable)
  • (expr for iter_var in iterable if cond_expr)
# 生成器表达式
In [96]: even_nums = (i for i in range(1,11) if i%2 == 0) 

In [97]: type(even_nums)                                  
Out[97]: generator                                        

# 生成器函数
In [98]: def get_even_number(max):                        
    ...:     for i in range(1, max):                      
    ...:         if i%2 == 0:                             
    ...:             yield i                              
    ...:                                                  

In [99]: even_nums_1 = get_even_number(11)                

In [100]: type(even_nums_1)                               
Out[100]: generator

# 手动遍历生成器
In [104]: even_nums = (i for i in range(1,11) if i%2 == 0)

In [105]: while True:
     ...:     try:
     ...:         print(next(even_nums))
     ...:     except StopIteration:
     ...:         break

表达式VS生成器:表达式的结果是直接会生成一个列表,实实在在占用内存。但是生成器表达式,是一种lazy load技术,返回的结果是一个生成器。当程序中使用到具体的列表项的时候,才会返回。

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

推荐阅读更多精彩内容

  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 18,910评论 17 410
  • PYTHON-进阶-ITERTOOLS模块小结转自wklken:http://wklken.me/posts/20...
    C_Y_阅读 951评论 0 2
  • 文/居里社 朗达﹒拜恩的著作《秘密》里提到:你当下的思想正在创造你的未来。你最常想的,将会出现在你的生命里,成为你...
    居里叶阅读 510评论 0 2
  • 2016年10月12日,爱码像一颗深埋地下许久的种子终于破土而出了。每个生命都是被寄予厚望的,每个名字都是有深刻寓...
    爱码爱自由阅读 302评论 1 4
  • 结论1:凡事最好先表明自己可提供的资源/帮助,再谈需要置换的资源/支持。 源于事件:两小时前跟别人联系给年轻姑娘小...
    查无此人_8924阅读 180评论 0 0