PythonDay06---迭代、列表生成式、生成器

Python之迭代、列表生成式、生成器

一、迭代

1.什么是迭代

说明:在Python中,通过for循环来遍历list、tuple、set、dict,这种遍历我们成为迭代(Iteration)。在Python中,迭代是通过 for … in 来完成的,而很多语言比如C或者Java,迭代list是通过下标完成的,比如Java代码:

int n = 0;
for (i = 0; i < list.length; i++) {
    n = list[i];
}

可以看出,Python的for循环抽象程度要高于Java的for循环。
因此,迭代操作就是对于一个集合,无论该集合是有序还是无序,我们用 for 循环总是可以依次取出集合的每一个元素。
注意: 集合是指包含一组元素的数据结构,我们已经介绍的包括:
(1)有序集合:list,tuple,str和unicode;
(2)无序集合:set
(3)无序集合并且具有 key-value 对:dict

迭代与按下标访问数组最大的不同是,后者是一种具体的迭代实现方式,而前者只关心迭代结果,根本不关心迭代内部是如何实现的。

2.索引迭代

说明:索引迭代就是通过迭代list或者tuple得到元素对应的下标。
语法:enumerate()函数
eg:

L = ['wang', 'zhao', 'li']
for index, name in enumerate(L):
    print(index, '-', name)

结果:

0 - wang
1 - zhao
2 - li

注意:enumerate()函数是把['wang', 'zhao', 'li']变成了[(0, 'wang'), (1, 'zhao'), (2, 'li')]即把每个元素变成了一个tuple,通过以下代码可以看出:

L = ['wang', 'zhao', 'li']
for t in enumerate(L):
    index = t[0]
    name = t[1]
    print(index, '-', name)

结果:

0 - wang
1 - zhao
2 - li
3.迭代dict的value

说明:用values()方法,前面PythonDay03中已经提到过。
了解:python3版本以前还有itervalues()方法可以获取dict的value,现在没有了。

4.同时迭代dict的key和value

语法:items()方法
eg:

d = {
    'wang':100,
	'zhao':80,
	'li':60
}
for key, value in d.items():
    print(key, '-', value)

结果:

wang - 100
zhao - 80
li - 60

二、列表生成式

1.生成列表

eg:要生成列表[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

L = []
for x in range(1, 11):
    L.append(x * x)
print(L)

结果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是,用循环的方式来实现太繁琐,这里介绍新知识,用列表生成式可以用一行语句代替循环生成上面的list:

print([x * x for x in range(1, 11)])

结果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

2.复杂表达式

eg:一个复杂的列表生成式生成一个 HTML 表格:

d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.items()]
print('<table>')
print('<tr><th>Name</th><th>Score</th><tr>')
print('\n'.join(tds))
print('</table>')

结果:

<table>
<tr><th>Name</th><th>Score</th><tr>
<tr><td>Adam</td><td>95</td></tr>
<tr><td>Lisa</td><td>85</td></tr>
<tr><td>Bart</td><td>59</td></tr>
</table>

在HTML中显示效果为:

NameScore
Adam95
Lisa85
Bart59

注意:join()方法可以把一个 list 拼接成一个字符串。
eg:

L = ['1', '2' ,'3', '4']
print('|'.join(L))   #注意:list要想能拼成字符串,这里的list的元素必须为字符串
                     #join()方法是字符串特有的方法,必须是字符串才能用该方法

结果:1|2|3|4
而字符串的split()方法与join()方法刚好相反:

s = '1|2|3|4'
print(s.split('|'))

# 结果:
['1', '2', '3', '4']
3.条件过滤

eg:去掉列表[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]中为偶数平方的数

L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print([x * x for x in L if x % 2 == 1])

结果:[1, 9, 25, 49, 81]
小测试:请编写一个函数,它接受一个 list,然后把list中的所有字符串变成大写后返回,非字符串元素将被忽略。
代码:

L = ['Hi', 'my name is wang', 1001]
def list_str_upper(L):
    return [x.upper() for x in L if isinstance(x, str)]
print(list_str_upper(L))

结果:['HI', 'MY NAME IS WANG']

4.多层表达式

说明:for循环可以嵌套,因此,在列表生成式中,也可以用多层 for 循环来生成列表。
eg:利用 3 层for循环的列表生成式,找出对称的 3 位数。例如,121 就是对称数,因为从右到左倒过来还是 121。

print([x * 100 + y * 10 + n for x in range(1, 10) for y in range(10) for n in range(10) if x == n])

结果:

[101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]

三、生成器

1.什么是生成器

说明:列表元素可以按照某种算法,在循环的过程中不断推算出后续的元素。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
作用:使用生成器,可以减少存储数据空间的占用,节省内存空间。

2.创建生成器

(1)把一个列表生成式的[]改成(),就创建了一个generator。
eg:

L = [x * x for x in range(10)]
print(L)
g = (x * x for x in range(10))
print(g)

结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x1022ef630>

(2)如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
eg:斐波拉契数列的推算规则

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b        #本来应该是print(b)
        a, b = b, a + b
        n = n + 1
    return 'done
f = fib(6)
print(f)

结果:<generator object fib at 0x104feaaa0>
注意:a, b = b, a + b等价于:

t = (b, a + b) # t是一个tuple
a = t[0]
b = t[1]
3.遍历生成器

(1)不断用next()函数,每用一次next()函数就是得到下一个元素
eg:

g = (x * x for x in range(10))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

结果:

0
1
4
9
16

(2)用for语句迭代
eg:

g = (x * x for x in range(10))
for n in g:
print(n)

结果:

0
1
4
9
16
25
36
49
64
81

注意:最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
小练习:打印出杨辉三角的前十行(用生成器)。
代码:

def triangles():
    n = 0
    L = [1]
    while n < 10:
        yield L
        L.append(0)
        L = [L[i-1] + L[i] for i in range(len(L))]
        n += 1
b = triangles()
for x in b:
    print(x)

结果:

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

小结

  • 凡是可作用于for循环的对象都是Iterable类型;
  • 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
  • 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我会尽力回答你的问题。 首先,让我们来谈谈 Python 中的异常处理。在 Python 中,异常是程序在运行时遇到的错误或问题,它会导致程序停止运行并抛出一个异常。为了避免这种情况,我们可以使用 try/except 块来捕获并处理异常。例如: ``` try: # some code that might raise an exception except SomeException: # handle the exception ``` 其中,SomeException 是你想要捕获的异常类型。当代码运行到 try 块中的代码时,如果出现了 SomeException 异常,那么 except 块中的代码就会被执行。 接下来,让我们来谈谈 Python 中的对象。在 Python 中,一切都是对象,包括数字、字符串、函数等等。对象有一个类型,它定义了对象可以执行的操作。例如,数字类型可以执行加、减、乘等操作,字符串类型可以执行拼接、切片等操作。你也可以创建自己的对象,并定义它们的类型和操作。 最后,让我们来谈谈 Python 中的迭代器。迭代器是一种对象,它可以让你逐个访问一个序列中的元素。Python 中的迭代器是通过 __iter__ 和 __next__ 方法实现的。__iter__ 方法返回一个迭代器对象,__next__ 方法返回序列中的下一个元素。例如: ``` class MyIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.data): raise StopIteration result = self.data[self.index] self.index += 1 return result my_iter = MyIterator([1, 2, 3]) for item in my_iter: print(item) ``` 在上面的例子中,我们创建了一个名为 MyIterator 的迭代器对象。它有一个 data 属性,表示要迭代的序列,以及一个 index 属性,表示当前迭代的位置。__iter__ 方法返回 self,表示它本身就是一个迭代器对象。__next__ 方法返回序列中的下一个元素,并将 index 属性加 1。当迭代器遍历到序列末尾时,会抛出 StopIteration 异常,表示迭代结束。 希望这些信息能够对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElegantCodingWH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值