循环、使用dict和set

发布于:2024-05-16 ⋅ 阅读:(53) ⋅ 点赞:(0)

循环

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

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

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

>>> list(range(5))
[0, 1, 2, 3, 4]

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

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

第二种循环是while循环:

sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)
2500

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

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

使用dict和set

dict

Python内置了字典,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度
举例:
两个list查找,list越长,耗时越长:

names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]

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

>>> dict = {'Michael' : 95, 'Bob' : 75, 'Tracy' : 85}
>>> dict['Michael']
95

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

>>> d['Adam'] = 67
>>> d['Adam']
67

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

>>> d['Jack'] = 90
>>> d['Jack']
90
>>> d['Jack'] = 88
>>> d['Jack']
88

key不存在,会报错:

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

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

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

注意:返回None的时候Python的交互环境不显示结果。
要删除一个key,用pop(key)方法,对应的value也会删除:

>>> 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:

>>> 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作为输入集合:

>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}

显示的顺序不代表set有序。
重复元素在set中自动被过滤:

>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

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

>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}

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

>>> s.remove(4)
>>> s
{1, 2, 3}

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

>>> 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,看看是否会报错。

>>> 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内部的内容是会变化的:

>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']

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

>>> 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中:

>>> 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])
>>> 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/