一:for循环的定义
for循环是对可迭代对象进行迭代的过程。
看到这个定义,很多萌新肯定会问了:到底什么是迭代,什么是可迭代对象呢?首先,迭代就是从可迭代对象逐个读取元素,直到可迭代对象中的元素都被读取出来。而可迭代对象可以看成一种内部有很多元素的容器。
好吧,大家应该对for循环的两个定义有了更清楚的认识了吧。但是,细心的小伙伴肯定会说,我还是不是很明白,当一个对象来了,我怎么知道这个对象是不是可迭代对象呢?
很简单,任何可迭代对象都有一个内置的方法---即_iter_(),而且这个方法会返回一个迭代器。(这里的迭代器会在后面讲解,有疑问的小伙伴们可以先放下这个问题,接着往下看!!)
接下来,我会对5种不同的数据类型对象进行迭代,并在for循环中进行对对象进行各种操作(插入、删除、修改、添加等等)。
二:5种对象在for循环中的操作
一:String对象的for循环
首先,String基本数据类型是不可变的对象。(不可变对象中的”不变“指:对象中所指内存中的值不可被改变)
String对象可进行的操作是:删除整个字符串、切片
修改元素:
>>> str="1234567"
>>> for x in str:
... if x=="2":
... str[2]="888"
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
TypeError: 'str' object does not support item assignment
当尝试修改String对象时,会产生一个错误:即String对象不支持修改。(因为String对象是不可变的!!)
删除整个字符串:
>>> str="1234567"
>>> del str
>>> print(str)
<class 'str'>
String对象的其他方法有:
str.replace('old','new') 旧字符串替换为新字符串
str.strip() 去两边空格
str.upper() 转换为大写字符串
str.lower() 转换为小写字符串
str.swapcase() 大小写互换
二:列表基本数据类型对象的for循环
列表基本数据类型是可变的对象。(可变对象中的”变“指:对象中所指内存中的值可被改变)
列表对象可进行的操作有:添加元素(添加到末尾)、插入元素
添加元素到末尾:
>>> list=[1,2,3,4,5]
>>> for x in range(len(list)):
... list.append(6)
...
>>> print(list)
[1, 2, 3, 4, 5, 6, 6, 6, 6, 6]
插入元素:
>>> list=[1,2,3,4,5]
>>> for x in range(len(list)):
... list.insert(2,6)
...
>>> print(list)
[1, 2, 6, 6, 6, 6, 6, 3, 4, 5]
删除元素:
[1, 2, 6, 6, 6, 6, 6, 3, 4, 5]
>>> list=[1,2,3,4,4,5]
>>> for x in range(len(list)):
... if list[x]==4:
... del list[x]
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range
在对列表对象进行for循环的删除和添加元素中,我们可以发现:在删除元素时会越界(导致下标超过列表长度),而在添加元素时也会产生类似问题(这里楼主还不知道相应的例子!!)。
列表对象的其他方法:
list.count(obj):统计某个元素在列表中出现的次数
list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.index(obj):从列表中找出某个值第一个匹配项的索引位置
list.remove(obj):移除列表中某个值的第一个匹配项
list.reverse():反向列表中元素
list.sort([func]):对原列表进行排序
三:元组基本数据类型对象的for循环
元组基本数据类型是不可变的。其中的元素不能进行修改!!
对元组对象进行的操作有:删除(只能删除整个元组)、切片
遍历元组:
>>> tuple=(1,2,3,4,5)
>>> for x in range(len(tuple)):
... print(tuple[x])
...
1
2
3
4
5
删除元组中的元素:
>>> tuple=(1,2,3,4,5)
>>> for x in range(len(tuple)):
... del tuple[x]
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: 'tuple' object doesn't support item deletion
我们可以看出,当试图删除元组对象的某个元素时,会报错!!(即元组对象不能删除元组中的单个元素)
删除整个元组:
>>> tuple=(1,2,3,4,5)
>>> del tuple
>>> print(tuple)
<class 'tuple'>
此时,可以删除元组。(元组被完全删除)
元组对象的其他方法:
tuple.index(obj):从元组中找出某个值第一个匹配项的索引值
tuple.count(obj): 统计某个元素在元组中出现的次数
四:字典基本数据类型的for循环
字典数据类型是可变的,无序的。
字典数据类型对象由键值对组成,键名必须是唯一的(即必须为不可变的对象--Number、String、Tuple),值可以为任意类型(且不是唯一的)。
对字典对象进行的操作有:删除单个元素、删除整个字典对象、清空、修改等等
遍历字典对象的值:
>>> dic={"a":1,"b":2,"c":3}
>>> for x,y in dic.items():
... print(dic[x])
...
1
2
3
>>> dic={"a":1,"b":2,"c":3}
>>> for x,y in dic.items():
... print(dic[x])
...
1
2
3
删除单个元素:
>>> dic={"a":1,"b":2,"c":3}
>>> for x in dic.keys():
... if x=="b":
... del dic["b"]
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
我们可以发现,这种方法不能删除单个元素,那么应该怎么做呢?真正的方法如下:
>>> dic={"a":1,"b":2,"c":3}
>>> l=list(dic.keys())
>>> for x in l:
... del dic[x]
...
>>> print(dic)
{}
>>> dic={"a":1,"b":2,"c":3}
>>> l=list(dic.keys())
>>> for x in l:
... dic.pop(x)
...
1
2
3
>>> print(dic)
{}
此时我们才是真正得将单个元素从字典中删除了!!
添加元素:
>>> dic={"a":1,"b":2,"c":3}
>>> l=list(dic.keys())
>>> for x in l:
... dic[x+"m"]=6
...
>>> print(dic)
{'a': 1, 'b': 2, 'c': 3, 'am': 6, 'bm': 6, 'cm': 6}
删除整个字典:
>>> dic={"a":1,"b":2,"c":3}
>>> del dic
>>> print(dic)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'dic' is not defined
清空字典:
>>> dic={"a":1,"b":2,"c":3}
>>> dic.clear()
>>> print(dic)
{}
字典对象的其他方法:
D.items() 返回表示D项的(键,值)对列表
D.keys() 返回D键的列表
D.values() 返回D值的列表
D.iteritems() 从D.items()返回的(键,值)对中返回一个可迭代的对象
D.iterkeys() 从D的键中返回一个可迭代对象
D.itervalues() 从D的值中返回一个可迭代对象
五:集合基本数据对象的for循环
集合分为两种类型:set(可变集合)和frozenset(不可变集合)。
集合是无序的、不重复的。
对集合对象可进行的操作:添加元素、删除元素、交集、并集等等
遍历集合(set):
>>> ss={1,2,3,4,5}
>>> for x in ss:
... print(x)
...
1
2
3
4
5
注意:在遍历集合的时候可能不会按照当初创建集合时中元素的顺序输出。(因为集合是无序的!!)
删除元素:
>>> ss={1,2,3,4,5}
>>> for x in range(len(ss)):
... ss.remove(x+1)
...
>>> print(ss)
set()
添加元素:
>>> ss={1,2,3,4,5}
>>> for x in range(len(ss)):
... ss.add(x+9)
...
>>> print(ss)
{1, 2, 3, 4, 5, 9, 10, 11, 12, 13}
集合对象的其他方法:
setVar.discard(element) 在集合setVar中查找element元素,如果存在则删除;如果没找到,则什么也不做
s.pop() 删除并返回set类型的s中的一个不确定的元素,如果为空引发KeyError错误
s.clear() 清空s集合中的所有元素
集合的操作符: 交集& 并集| 差集- 等于== 不等于!= 大于> 小于< 大于等于>= 小于等于<=
注意:frozenset集合与的区别在于frozenset一旦创建就不能再改变(即不能增删改等类似的操作)
三:for循环的原理
想必学习过其他语言的程序员也一定看到过for循环,但是python的for循环与其他语言的for循环是不同的。(关于这点,让楼主吃了很多苦头!!)
for循环执行的原理:
1、先判断对象是否为可迭代对象,不是的话直接报错,抛出TypeError异常,是的话,调用__ iter__()方法,返回一个迭代器
2、不断地调用迭代器的__next__()方法,每次按序返回迭代器中的一个值,将值赋值给in前面的变量(每次赋值之后就执行一次for循环体的代码)
3、迭代到最后,没有更多元素了,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者
四:遗留问题(待以后解决)
对于list对象,for循环的可迭代对象参数为list对象本身时,可以进行删除和添加元素。
对于set和字典对象,for循环的可迭代对象参数为set和字典对象本身时,不可以进行删除和添加元素
原因:因为可迭代对象如果在迭代过程中长度发生了变化,就会引发 Runtime Error 。