循环、使用dict和set

循环

Python的循环有两种,一种是for...in,依次把list或tuple中的每个元素迭代出来:

python 复制代码
# -*- coding: utf-8 -*-
names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)
python 复制代码
Michael
Bob
Tracy

range()函数,可以生成一个整数序列,再通过list()函数可以转换为list:

python 复制代码
>>> list(range(5))
[0, 1, 2, 3, 4]

那么计算1-100的整数之和就可以:

python 复制代码
# -*- coding: utf-8 -*-
sum = 0
for x in range(101):
    sum = sum + x
print(sum)
python 复制代码
5050

第二种循环是while循环:

python 复制代码
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)
python 复制代码
2500

练习

请利用循环依次对list中的每个名字打印出Hello, xxx!

python 复制代码
# -*- coding: utf-8 -*-
L = ['Bart', 'Lisa', 'Adam']
for str in L:
    print(f'Hello, {str}!')
python 复制代码
Hello, Bart!
Hello, Lisa!
Hello, Adam!
  • break
python 复制代码
# -*- coding: utf-8 -*-
n = 1
while n <= 100:
    if n > 10: # 当n = 11时,条件满足,执行break语句
        break # break语句会结束当前循环
    print(n)
    n = n + 1
print('END')
python 复制代码
1
2
3
4
5
6
7
8
9
10
END
  • continue
python 复制代码
# -*- coding: utf-8 -*-
n = 0
while n < 10:
    n = n + 1
    if n % 2 == 0: # 如果n是偶数,执行continue语句
        continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行
    print(n)
python 复制代码
1
3
5
7
9

使用dict和set

dict

Python内置了字典,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度

举例:

两个list查找,list越长,耗时越长:

python 复制代码
names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]

用dict实现就只需要直接根据名字查找成绩,无论表多大,查找速度都不会变慢:

python 复制代码
>>> dict = {'Michael' : 95, 'Bob' : 75, 'Tracy' : 85}
>>> dict['Michael']
95

把数据放入dict,还可以通过key放入:

python 复制代码
>>> d['Adam'] = 67
>>> d['Adam']
67

多次对一个key放入value,会覆盖:

python 复制代码
>>> d['Jack'] = 90
>>> d['Jack']
90
>>> d['Jack'] = 88
>>> d['Jack']
88

key不存在,会报错:

python 复制代码
>>> d['Thomas']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Thomas'

要避免key不存在的错误,有两种方法:

  • 通过in判断:
python 复制代码
>>> 'Thomas' in d
False
  • 通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:
python 复制代码
>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

注意:返回None的时候Python的交互环境不显示结果。

要删除一个key,用pop(key)方法,对应的value也会删除:

python 复制代码
>>> dict.pop('Bob')
75
>>> dict
{'Michael': 95, 'Tracy': 85}

dict是无序的,和list比较,dict有以下几个特点:

  1. 查找和插入的速度极快,不会随着key的增加而变慢;
  2. 需要占用大量的内存,内存浪费多。
    而list相反:
  3. 查找和插入的时间随着元素的增加而增加;
  4. 占用空间小,浪费内存很少。
    所以,dict是用空间来换时间。
    dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象

这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。

要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:

python 复制代码
>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

set

set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。

要创建一个set,需要提供一个list作为输入集合:

python 复制代码
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}

显示的顺序不代表set有序。

重复元素在set中自动被过滤:

python 复制代码
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

通过add(key)方法可以添加元素到set中:

python 复制代码
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}

通过remove(key)方法可以删除元素:

python 复制代码
>>> s.remove(4)
>>> s
{1, 2, 3}

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

python 复制代码
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部"不会有重复元素"。试试把list放入set,看看是否会报错。

python 复制代码
>>> s1 = set([[1,2], 2, 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

再议不可变对象

str是不变对象,而list是可变对象,对于可变对象,如list,进行操作,list内部的内容是会变化的:

python 复制代码
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']

而对于不可变对象,比如str进行操作:

python 复制代码
>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'

虽然用字符串的replace()方法变出了Abc,但变量a最后仍然是abca是一个变量,指向的内容是abc,当调用a.repalce('a', 'A')时,方法replace是作用在字符串abc上,并没有改变abc的内容,而是创建了一个新字符串Abca仍指向原来的字符串abc

所以,对于不变对象来说,调用对象自身的任何方法,也不会改变对象自身的内容,相反,这些方法会创建新的对象并返回,这样就保证了不可变对象永远是不可变的。

更新知识

注意,dict的创建可以{}也可以dict(),而set的创建也是{}set(),不要认为set是用()创建,这创建的是tuple,那么试试把tuple放到dict或set中:

python 复制代码
>>> s = {(1, [2, 3]), 1, 2}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> s = {(1, 2, 3), 1, 2}
>>> s= set([(1, [2, 3]), 1, 2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> s= set([(1, 2, 3), 1, 2])
python 复制代码
>>> d = {(1, 2, 3) : 'value1', 2 : 'value2', 3 : 'value3'}
>>> d
{(1, 2, 3): 'value1', 2: 'value2', 3: 'value3'}
>>> d = {(1, [1, 2], 3) : 'value1'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

可以看出,(1, 2, 3)这种元素都是不变对象的可以放进去,但元素里有list这种可变对象的(1, [2, 3])放不进去。

参考https://www.liaoxuefeng.com/

相关推荐
人工智能训练15 小时前
Windows系统Docker中Xinference 集群无法启动的解决方法
linux·运维·服务器·windows·docker·容器·xinference
程序员霸哥哥15 小时前
XYplorer(多标签文件管理器) v27.20.0700 / 28.00.1200 多语便携版
windows·macos·软件工程·mac·应用软件·xyplorer
公子小六15 小时前
推荐一种手动设置异步线程等待机制的解决方案
windows·microsoft·c#·.net
沐雪轻挽萤15 小时前
pytorch模型部署基础知识
人工智能·pytorch·python
xxxxxmy16 小时前
相向双指针—接雨水
python·相向双指针
nix.gnehc16 小时前
PyTorch数据加载与预处理
人工智能·pytorch·python
兮动人16 小时前
解决微软应用商店 (Microsoft store) 打不开,无网络连接的问题!
网络·microsoft
无尽星海max16 小时前
意外惊喜!微软宣布 Windows 10 免费安全更新再延长一年!
microsoft·支持
托斯沃尔16 小时前
为什么Microsoft Store(微软应用商店)下载速度特别慢?
windows·microsoft
Sindy_he16 小时前
2025最新版微软GraphRAG 2.0.0本地部署教程:基于Ollama快速构建知识图谱
python·microsoft·大模型·知识图谱·rag