在学习python之前,我比较熟悉的语言也就是java了。因此,在学习的过程中会将python的一些语言特性和java进行一定的对比。下面主要说一下python的以下高级特性:切片、迭代、列表生成式、生成器、迭代器。
切片
切面操作符的一般格式为:L[start: end : step]
其中start表示起始索引,end表示结束索引,step表示切片间隔数。其中start、end和step都可以省略,第二个冒号可以省略,而第一个冒号不可以省略。如果省略start,则从序列首开始,如果省略end,则停止在序列尾。step省略,默认间隔数为1。下面还是通过一些例子来说明切面的具体使用。
#定义一个list
L = [1, 2, 3, 4, 5, 6, 7,8, 9]
L[1:3] # 结果为:[2, 3],不包括end=3处的元素。
L[1:8:2] #结果为:[2, 4, 6, 8],元素的索引的间隔为2
L[1:3:1] # 结果为[2, 3],和L[1:3]相同
#注1:step的值不仅可以为正数,同时可以为负数。为正数时,需要保证start索引对应的元素的位置在end索引对应元素的左边,否则会返回一个空的列表(为什么强调位置呢,而不是强调start和end的大小呢?因为start和end的值也可以为负数,就算start的值小于end,start和end对应的元素的位置也是不确定的)。step为负数时,需要保证start索引对应的元素的位置在end索引对应元素的右边,否则会返回一个空列表。
L[3:1] #结果为:[],根据注1可以解释。
L[-1:-3]#结果为:[],根据注1可以解释。和L[-1:-3:1]相同
L[-1:-3:-1]#结果为:[9, 8]
L[-3:-1] #结果为:[7, 8]
L[::]#结果为:[1, 2, 3, 4, 5, 6, 7,8, 9]
切片不仅可以作用list,同时可以用于tuple、str类型等。大家可以多多使用下,体会其中的方便和操作的灵活性。
在Java中,比如List,最常见的就是ArrayList和LinkedList,而适合插入和删除的是LinkedList,适合查找的是ArrayList。如果我们想构建一个新的List,最常见的就是使用for循环。如下例子,和切片的简单操作没法比。
List<String> getNeList(list) {
List<String> newList = new ArrayList<>();
for(int i = start; i < end; i++) {
newList.add(list.get(i));
}
return newList;
}
迭代
迭代又可称为遍历。在python中,迭代是通过for…in来完成的,而在Java中主要有两种方式进行遍历,一种是通过forEach来实现遍历,第二种直接使用索引下标来实现。
先给个Java遍历的例子:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//通过索引下标进行遍历
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//通过forEach进行遍历
for(int value : list) {
System.out.println(value);
}
要想使用for…in进行迭代,则对象首先是可迭代对象,可以通过isinstance来判断对象是否是可迭代对象:
isinstance("ABC", Iterable) #True
isinstance([1,2,3], Iterable) # True
isinstance(123, Iterable) # False
下面针对不同的情况给出例子,具体的使用请见代码中的注释
dict = {"a":1, "b":2, "c":3}
#默认情况下,遍历dict时,是将字典的键输出
for key in dict:
print(key)
#如果想遍历字典中的值,可以调用values()函数
for value in dict.values():
print(value)
#同时遍历字典中的键和值,调用items()函数
for key, value in dict.items():
print(key, value)
#对于list
list = [1, 2, 3]
for value in list:
print(value)
#在遍历list时,如果同时想将索引也给显示出来,可以调用enumerate()函数
for index, value in enumerate(list):
print(index, value);
列表生成式
列表生成式,故名思义,根据我们的需求,根据需要生成我们需要的列表。在python中,这点不得不服,的确简单。下面根据例子进行说明:
list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
#构建由list每个元素的平方组成的一个新的列表
list1 = [x * x for x in list]
#构建由list中元素为偶数的平方组成的一个新的列表
list2 = [x * x for x in list if x % 2 == 0]
#构造“ABC”和“DEF”中的任意一个字母组成的全排列,使用两层for循环
list3 = [m + n for m in "ABC" for n in "DEF"]
#for循环传递两个参数
dict = ["a":1, "b":2, "c":3]
list4 = [k + "=" + v for k, v in dict.items()]
生成器
通过列表生成式,我们能够直接生成一个完整的列表,但是当列表的元素过多,以致不能够用内存进行存储。我们可以考虑使用一种算法,需要的元素可以通过算法直接推出来,而不是直接生成全部的元素。这种机制称为生成器:generator。generator保存的是一种算法,每次调用next(generator)都会得到下一个元素,如果没有下一个元素,抛出StopIteration异常。
通过以下例子进行说明:
#列表生成器的格式
list1 = [x for x in range(11)] #结果为[1,2,3,4,5,6,7,8,9,10]
#第一种得到生成器的方法,是将[]换成()
g = (x for x in range(11)) #得到一个generator,结果可以调用next(g)
#得到结果
next(g) #输出0
next(g) # 输出1
#第二种获得生成器的方法:使用yield关键字,如果一个函数中包含关键字yield,则此函数就不在是普通的函数,而是一个generator。
def odd():
print("step 1")
yield 1
print("step 2")
yield 2
print("step 3")
yield 3
#在上面的odd函数定义中,返回值就是一个generator
o = odd()
next(o)#输出为step 1 1
next(o)#输出为step 2 2
迭代器
可被for循环直接调用的对象称为可迭代对象;
可以被next()函数调用,并不断返回下一个值的对象称为迭代器,generator对象都是迭代器。
可以通过iter()函数将list、tuple、str等转为迭代器。
it = iter([1, 2, 3, 4])
while True:
try:
x = next(it)
except StopIteration:
break