hand first python 选读(1)
列表(list)
基本操作
比如说我要整理一个近期热映的电影列表:
movies = ["venom", "my neighbor totor", "aquaman"] print(movies) # ['venom', 'my neighbor totor', 'aquaman'] print(len(movies)) # 3 print(movies[1]) # my neighbor totor
列表很像数组,但功能超越数组。列表都是从0开始的,python中列表无需事先声明类型。
从列表后面加上一个新的元素,比如说加个“无名之辈”,是append
方法。
movies.append('a cool fish') print(movies) # ['venom', 'my neighbor totor', 'aquaman','a cool fish']
删除列表最后一个元素:pop
方法。
movies.pop() print(movies) # ['venom', 'my neighbor totor']
两个列表相衔接,用的是extend
方法。
movies.extend(['dying to survive', 'detective conan']) print(movies) # ['venom', 'my neighbor totor', 'aquaman', 'dying to survive', 'detective conan']
我想在某个条件下删除一个元素,同时加上一个元素,涉及remove
和insert
方法。
movies.remove('venom') print(movies) # ['my neighbor totor', 'aquaman'] movies.insert(len(movies),'venom') print(movies) # ['my neighbor totor', 'aquaman','venom']
python中列表可以放任何类型的数据。
循环
处理列表需要各种迭代方法。是时候用for...in循环了
for movie in movies: print(movie) # venom # my neighbor totor # aquaman
同理while循环也是可以的
count=0 while count<len(movies): print(movies[count]) count+=1
一般都推荐for循环
列表当然也能嵌套,我们可以用isinstance
方法检测之:
movies = ["venom", ["my neighbor totor", "aquaman"]] print(isinstance(movies,list)) # true
if else
如果我想把这个嵌套列表单独打印出来,可以这么操作
movies = ["venom", ["my neighbor totor", "aquaman"]] for movie in movies: if isinstance(movie, list): for _movie in movie: print(_movie) else: print(movie) # venom # my neighbor totor # aquaman
函数与递归:多层嵌套的扁平化
给这个列表再加一层:
movies = ["venom", ["my neighbor totor", ["aquaman"]]]
用上节来处理多层嵌套,会导致大量重复而不优雅的代码。
首先使用函数让代码更加优雅:
movies = ["venom", ["my neighbor totor", ["aquaman"]]] def flatten(_list): if(isinstance(_list, list)): for _item in _list: flatten(_item) else: print(_list) flatten(movies)
为了巩固所学:再举一个通过递归生成斐波拉契数列第n项的例子:
斐波那契数列(fibonacci sequence),指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:f(1)=1,f(2)=1, f(3)=2,f(n)=f(n-1)+f(n-2)(n>=4,n∈n*)
def fib(n): if n < 1: return 'error' if n == 1 or n == 2: return 1 else: return fib(n-1)+fib(n-2) print(fib(6)) # 8
虽然很简洁,但是n>100就报错了。因为python的递归支持100层
函数
模块化开发
把上一章的flatten函数单独用base.py存起来,它就打包为一个模块。
除了之前提到的,用#
注释,还可以用三重"""
作为python的注释。
再同一个命名文件夹下重新创建一个app.py文件:
import base as util movies = ["venom", ["my neighbor totor", ["aquaman"]]] print(util.flatten(movies)) # 预期结果
列表更多的内置方法
先学习以下内置的方法(bif)
- list() :工厂函数,创建一个新的列表
- next() : 返回一个迭代结构(如列表)中的下一项
- id() :返回一个数据对象的唯一标识(内存地址)
>>> id(b) 140588731085608
- int() :将一个字符串如
'5'
转化为5
- range() :返回一个迭代器,根据需要生成一个指定范围的数字
>>>range(10) # 从 0 开始到 10 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> range(1, 11) # 从 1 开始到 11 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> range(0, 10, 3) # 步长为 3 , 迭代终点不超过10 [0, 3, 6, 9]
- enumerate() :把单个数组创建为带有索引号的成对列表
>>>seasons = ['spring', 'summer', 'fall', 'winter'] >>> list(enumerate(seasons)) [(0, 'spring'), (1, 'summer'), (2, 'fall'), (3, 'winter')] >>> list(enumerate(seasons, start=1)) # 下标从 1 开始 [(1, 'spring'), (2, 'summer'), (3, 'fall'), (4, 'winter')]
升级你的模块:参数
扁平化打印只能看到每个数组最小的元素,考虑用缩进来体现彼此的关系。那怎么做呢?
提示:用range方法实现。
事实上在打印时只需要知道每次迭代的深度,就好处理了。因此需要引入第二个参数
# base.py def flatten(_list,level=0): if(isinstance(_list, list)): for _item in _list: flatten(_item,level+1) else: for step in range(level): print("\t", end='') print(_list)
# app.py import base as util movies = ["venom", ["my neighbor totor", ["aquaman"]], ["my neighbor totor", ['000',["aquaman"]]], 'aaa', ['aquaman'],'sadas'] print(util.flatten(movies))
效果出来了。但还有不满意的地方。如果要兼容过去的写法怎么办?
def flatten(_list, count=false, level=0): if(isinstance(_list, list)): for _item in _list: flatten(_item,count,level+1) else: if count: for step in range(level): print("\t", end='') print(_list) else: print(_list)
调用时默认就是不缩进。