迭代 Iterable
list
、tuple
、str
、bytes
、dict
、range
、generator
、set
判断是否为可迭代对象
from collections.abc import Iterable
isinstance([1,2,3], Iterable)
切片
- 可迭代对象均可切片,返回类型和原来相同
- 取出从m项开始的n个元素,每s个取一个
- 省略
m
则为0,省略n
则为到最后一个为止,省略:s
- 若全省略则
L[:]
,等于拷贝
newL=L[m:n(:s)]
x=[1,2,3,4,5]
x[1]#2
x[1:3]#[2,3]
x[:3]#[1,2,3]
x[1:]#[2,3,4,5]
x[:]#[1,2,3,4,5]
len
len()
函数可以获得可迭代对象的长度,如list
/tuple
元素的个数、dict
键值对的个数、str
字符数、bytes
字节数
range
返回一个可迭代对象,通常配合for in使用
可以通过list
把range对象转化为列表
range(stop)
range(start, stop[, step])
for in
可使用for...in
对可迭代对象进行迭代
不同于js的for...of
和for...in
,python的for...in
根据迭代对象不同,有不同的迭代结果:
-
list
、tuple
、range
默认迭代的是value
如果要迭代下标,可以用enumerate()
for item in list:
pass
for index,value in enumerate(list):
pass
for value in range(len(list)):
pass
-
dict
默认迭代的是key
对象本身不支持迭代,可通过obj.__dict__
转为字典,或dir(obj)
方法取得属性列表,再进行迭代
for key in dict:
pass
for value in dict.values():
pass
for key,value in dict.items():
pass
# 本质上为解构赋值,如下
for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
推导式(列表、字典、集合)
书写方便,且执行效率远远高于通过循环生成列表/字典/集合
注意元组没有解析式,当使用()
时会生成generator
l = [i+1 for i in range(1,11) if i<5]
#[2, 3, 4, 5]
d = {i: j.upper() for i, j in zip(range(1, 3), 'abc')}
#{1: 'A', 2: 'B', 3: 'C'}
s = {x * x for x in range(10)}
#{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
- zip
把传入的参数打包成一个个元组,然后返回由这些元组组成的对象,以节约内存。可以使用 list() 转换zip对象以输出列表。
>>>list(zip(range(1, 3), 'abc'))
[(1,''a'),(2,'b'),(3,'c')]
while循环
Python中for只能对可迭代集合进行循环,复杂条件循环应使用while
while <条件语句>:
pass
break
退出循环
continue
提前结束本轮循环,直接开始下一轮循环
生成列表
range
range(num)
或range(startNum,endNum,[step])
(有头无尾)生成range
类型,再通过list()
转换成列表
列表生成式
[<执行操作> for x in <可迭代对象> (<逻辑判断>)]
如
[x * x for x in range(1, 11) if x % 2 == 0]
#[4, 16, 36, 64, 100]
生成器 generator
- 通过
next()
或for
循环执行 - 超出长度继续执行时会报
StopIteration
错误 - 既属于
Iterable
又属于Iterator
- 直接定义
类似列表生成式的方式,[]
改为()
g = (x * x for x in range(10))
#print(next(g))
for n in g:
print(n)
- 通过函数定义
存在yield
的函数视为generator函数
,函数执行时仅返回一个generator对象
,每次用next()
调用该generator对象
时执行函数,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
#next(fib(6))
for n in fib(6):
print(n)
等同于ES6
function* fib(max) {
var n = 0, a = 0, b = 1;
while (n < max) {
yield b;
({ a, b } = { a: b, b: a + b });
n = n + 1;
}
return 'done'
}
//fib(6).next()
for (item of fib(6)) {
console.log(item)
}
return
值可通过捕获StopIteration
中的value
获得
g = fib(6)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e:
print('Generator return value:', e.value)
break
迭代器 Iterator
- 可以被
next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。 -
Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算,因此节约内存空间,甚至可以表示一个无限大的数字流(如全体自然数) - 使用
iter()
函数为list
、dict
、str
等Iterable
添加Iterator
myIter=iter('abc')
print(next(myIter),next(myIter),next(myIter))#a b c
Python的for
循环本质上就是通过先转换成Iterator
再不断调用next()
函数实现
- 通过
list()
等可以把Iterator
转化回非Iterator
处理Iterable的方法
不同于JS中只有数组可以使用,Python中Iterable
均可使用以下方法
map
map将传入的函数依次作用到Iterable
的每个元素,并把整体结果作为新的Iterator
返回。
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)//[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
reduce把结果继续和Iterable
的下一个元素做累积计算
from functools import reduce
def fn(x, y):
return x * 10 + y
reduce(fn, [1, 3, 5, 7, 9])
# 13579
filter
filter把传入的函数依次作用于每个元素,根据返回值是True或False决定保留还是丢弃该元素,并把整体结果作为新的Iterator
返回。
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# [1, 5, 9, 15]
sorted
python2中可以使用cmp自定义排序规则,python3中已经废弃
- key
只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。 - reverse
排序规则,reverse = True 降序 , reverse = False 升序(默认)。
sorted(iterable, key=None, reverse=False)
L=[('b',2),('a',1),('c',3),('d',4)]
sorted(L, key=lambda x:x[1])
网友评论