数据类型

列表(List)

列表由一系列按特定顺序排列的元素组成,元素中可以包括字母,数字等,其中元素之间没有任何关系。

bicycles = ['trek','cannondale','redline','specialized'] #定义一个列表,包括四个元素
bicycles = [] #定义一个空的列表

如何访问列表

列表跟数组原理,通过指定位置进行访问。

print(bicycles[0]) #访问首个元素
print(bicycles[-1])#访问最后一个列表元素,注意,列表不能为空

修改列表元素

创建的大多数列表都是动态的,这意味着列表被创建后可以增删元素。

bicycles[0] = 'honda' #直接给元素赋予新的值即可

添加列表元素

往列表末尾添加元素,可以使用append()方法。

momrcyles = ['honda','yamaha','suzuki']
momrcyles.append('ducati')
print(momrcyles)

输出结果
['honda', 'yamaha', 'suzuki', 'ducati']

在列表中插入元素,可以用insert()方法,insert()使用时需要指定两个值,要插入的元素下标和元素值

momrcyles = ['honda','yamaha','suzuki']
momrcyles.insert(2,'ducati')
print(momrcyles)

输出结果
['honda', 'yamaha', 'ducati', 'suzuki']

从列表删除元素,如果知道要删除元素在列表的位置,可以使用del语句

momrcyles = ['honda','yamaha','suzuki']
del momrcyles[2]
print(momrcyles)

输出结果
['honda', 'yamaha']

使用pop()删除,有时候你要将元素从列表中删除,并接着使用它的值,方法pop()就可以实现,pop()不加上参数下删除列表末尾的元素,在圆括号里指定要删除元素索引即可来删除列表中任意位置的元素。

momrcyles = ['honda','yamaha','suzuki']
poped_momrcyles = momrcyles.pop()
first_momrcyles = momrcyles.pop(0)
print(momrcyles)
print(poped_momrcyles)
print(first_momrcyles)

输出结果
['yamaha']
suzuki
honda

根据元素值进行删除,有时候我们不知道元素在列表的具体位置,只知道元素的值,这个时候,我们就可以使用方法remove()。方法remove()只删除第一个指定的值,如果要删除的值要列表出现多次,就需要用循环来确保将每个值都删除。

momrcyles = ['honda','yamaha','suzuki']
momrcyles.remove('honda')
print(momrcyles)

输出结果
['yamaha', 'suzuki']

组织列表

在创建的列表里,排序往往是无法预测的,但有时候我们希望列表元素进行调整排列顺序。

使用sort()对列表进行永久排序,不指定参数是升序,指定reverse=True参数则是降序。

cars = ['bmw','audi','toyota','subaru']
cars.sort()
print(cars)
cars.sort(reverse=True)
print(cars)

输出结果
['audi', 'bmw', 'subaru', 'toyota']
['toyota', 'subaru', 'bmw', 'audi']

使用sorted()对列表进行临时排序,并不改变列表的顺序

cars = ['bmw','audi','toyota','subaru']
print(sorted(cars))
print(sorted(cars,reverse=True))
print(cars)

输出结果
['audi', 'bmw', 'subaru', 'toyota']
['toyota', 'subaru', 'bmw', 'audi']
['bmw', 'audi', 'toyota', 'subaru']

倒着打印列表,要反转列表元素的排列顺序,可使用方法reverse()。reverse()永久性修改列表元素的排序,如果想要恢复,只需要对列表再次使用reverse()即可。

cars = ['bmw','audi','toyota','subaru']
cars.reverse()
print(cars)

输出结果
['subaru', 'toyota', 'audi', 'bmw']

确定列表长度,使用函数len()可快速获取列表长度。

cars = ['bmw','audi','toyota','subaru']
print(len(cars))

输出结果
4

列表推导

列表推导算是Python的进阶知识,之所以在基础篇中提到,是因为在你阅读其他人源码时,经常会遇到这种写法。

这里只会简单介绍下它的语法,后续在高级特性里再仔细介绍。列表推导的表达式如下:

[表达式 for 迭代变量 in 可迭代对象 if判断(可忽略)]
			=
for 迭代变量 in 可迭代对象
	表达式

举个例子
list = [x*x for x in range(10)]

可以看到,使用列表推导不管多复杂的列表只需要一行代码就可以搞定了,列表推导将for循环和创建新元素的代码合并成一行,并自动附加新元素。

切片

切片是指获取列表部分元素。切片要求指定第一个元素和最后一个元素的索引。如果没指定第一个元素,默认为索引为0的元素。如果想选倒数的元素,只需要选择第一个元素为负数。下面来看举例说明:

import string
list = []
length = len(string.ascii_uppercase)

for i in range(length):
    list.append(string.ascii_uppercase[i])

print(list[0:3])
print(list[:3])
print(list[-3:])

输出结果如下
['A', 'B', 'C']
['A', 'B', 'C']
['X', 'Y', 'Z']

复制列表

在工作场景上,我们经常需要根据现有列表创建新的列表,如果只是用 = 进行引用,那么复制后副本和原列表的id是一样。这个时候就需要用到切片了。

import string
list = []
length = len(string.ascii_uppercase)

for i in range(length):
    list.append(string.ascii_uppercase[i])

copy_list = list[:]
copy_list[0] = 'change'

print(copy_list[0],list[0])
print(id(copy_list),id(list))

输出结果如下:
change A
2062511287232 2062511068800

嗯嗯,看来确实完全了拷贝,改变了副本内容,原列表不会受到影响,而且副本和原列表的id不一致。那我们接下来再看看另一个例子:

listA = [['A','B','C'],['D','E','F'],'G']
listB = listA[:]

listB[0][0] = 'Change'
listB[2] = 'H'

print(listA)
print(listB)

print(id(listA),id(listB))

输出结果如下:
[['Change', 'B', 'C'], ['D', 'E', 'F'], 'G']
[['Change', 'B', 'C'], ['D', 'E', 'F'], 'H']
1720709617280 1720709617472

奇怪了,改变了listB的内容,listA多维列表就受到影响了,而单列表就不会,而他们的id又是不一样的,这是什么问题?别急,接下来我们来仔细探索一番,彻底摸清列表切片的本质。

虽然id(listA) id(listB)为False,listA和listB确实不是同一个对象,但是他们的元素都是同一个对象id(listA[0]) id(listB[0])为True,因为列表里存储的是对象的引用!

列表list始终只是个容器,所以容器和它存储的对象不能混为一谈,所以对于这种多维列表,想要进行完全的拷贝,得使用copy.deepcopy()深度拷贝。

import copy
listA = [['A','B','C'],['D','E','F'],'G']
listB = copy.deepcopy(listA[:])

listB[0][0] = 'Change'

print(listA)
print(listB)

print(id(listA[0]),id(listB[0]))

输出结果如下
[['A', 'B', 'C'], ['D', 'E', 'F'], 'G']
[['Change', 'B', 'C'], ['D', 'E', 'F'], 'G']                                                                                                               
2375358923968 2375358889856

此时我们就得到了我们想要的完全拷贝,修改listB的内容listA不会受到影响

元组(tuple)

元组(tuple)是 Python 中另一个重要的序列结构,和列表类似,元组也是由一系列按特定顺序排序的元素组成。
元组和列表(list)的不同之处在于:

  • 列表的元素是可以更改的,包括修改元素值,删除和插入元素,所以列表是可变序列;

  • 而元组一旦被创建,它的元素就不可更改了,所以元组是不可变序列。

元组也可以看做是不可变的列表,通常情况下,元组用于保存无需修改的内容。下面来看具体例子:

tuple = ('100','50')
print(tuple)
tuple[0] = '200'

输出如下
('100', '50')
Traceback (most recent call last):                                                                                                                            E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S'
  File "h:\PythonProject\Part4\tuple.py", line 5, in <module>
    tuple[0] = '200'
TypeError: 'tuple' object does not support item assignment  

我们可以看到,程序报错了,这就是我们所说的,元组一旦被创建就只能被读取不能被修改。但是给元组重新赋值是合法的。我们需要存储一组值在程序的整个生命周期内都不变就可以使用元组。后续在高级特性中我们会介绍元组的高级用法。

元组还有另一种写法就是去掉左右括号,多个元素以逗号隔离开,注意一点的就是,当只有一个元素时,后面要加上逗号,这是为了与字符串,整数型区分开来。

tuple = ('100','50')
tuple = {'200'}
print(tuple)

输出如下:
{'200'}

字典(dict)

字典在工作中应用上很广泛,所以我们重点介绍下。在Python中,字典是一系列键值对。每个键都与一个值相关联,你可以使用键来访问相关的值。与键相关联的值可以是数,字符串,列表乃至字典。

在Python中,字典用于{}来表示。例如:

alien_0 = {'color':'green','points':'s'}

字典是一种动态结构,可随时在其中添加键值对,要添加键值对,可依次指定字典名,用方括号括起的键和相关联的值,如下:

dist['x'] = 200
dist['y'] = 100

删除键值对

对于字典中不再需要的信息,可使用del语句将相应的键值对彻底删除,使用del语句时,必须指定字典名和删除的键。

dicts = {'hello':'world'}
del dicts['hello']
print(dicts)

输出如下:
{}

访问不存在的键

当我们访问字典中不存在的键时,程序会报异常。而使用get()可以避免这个问题。

方法get()的第一个参数用于指定键,这是必要的;第二个参数为指定的键不存在时要返回的值,可选的,若没有指定则返回None。

dicts = {'hello':'world'}

print (dicts.get('test','python'))

输出如下:
python

循环遍历字典

遍历所有键值对

dicts = {'hello':'world','python':'Best'}

for key,value in dicts.items():
    print (key,value)

遍历所有的键,方法keys()并非只能用于遍历,实际上,它返回的是一个列表,其中包括了字典所有键。

dicts = {'hello':'world','python':'Best'}

for key in dicts.keys():
    print (key)

遍历所有的值

dicts = {'hello':'world','python':'Best'}

for value in dicts.values():
    print (value)

值得注意一点的是,字典在遍历过程中,不允许对字典进行删除,增加元素等操作。如果在遍历的过程中需要对字典进行操作,需要将字典转换成列表才可以。

集合(set)

Python 中的集合类型是一种无序容器,不允许有重复运算,由于底层使用了哈希存储,集合中的元素必须是 hashable 类型。集合和列表最大的区别在于集合中的元素没有顺序,无法通过索引运算访问元素。

在 Python 中,创建集合可以使用{}字面量语法,{}中需要至少有一个元素,因为没有元素的{}并不是空集合而是一个空字典

set1 = {1, 2, 3, 3, 3, 2}
print(set1)

set2 = {'banana', 'pitaya', 'apple', 'apple', 'banana', 'grape'}
print(set2)

set3 = set('hello')
print(set3)

set4 = set([1, 2, 2, 3, 3, 3, 2, 1])
print(set4)

流程条件

条件

每条if语句的核心都是一个值为True或False的表达式,这种表达式称为条件测试。如if判断为真,则执行if后的代码,如为False,则忽略这些。举个列子,判断一个人是否满18岁:

age = 20
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('underage')

根据Python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做。

也可以给if添加一个else语句,意思是,如果if判断是False,不要执行if的内容,去把else执行了。

以上代码为最常见的if-else结构,还有if-elif-else结构,常用于检查超过两个的情形。语法如下:

if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>

if语句执行有个特点,它是从上往下判断,如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elif和else。实际代码演示:

age = 20
if age >= 6:
    print('teenager')
elif age >= 18:
    print('adult')
else:
    print('kid')

循环

for 循环

for in 循环用于针对集合中的每个元素都执行一个代码块,一般是明确知道循环执行的次数。

import time

for i in range(3600):
    print('hello, world')
    time.sleep(1)

不知道大家注意到没有,循环条件中的 i 实际上在循环体并没有用到,按照编码习惯,我们可以用 _ 替代,虽然没什么用,但这会让你看起来更加专业。

for i in range(100):
    sum = sum + i
print(sum)

while 循环

如果要构造循环结构但是又不知道循环重复次数则用 while,while 循环不断运行,直到指定的条件不满足为止。

total = 0
i = 1
while i <= 100:
    total += i
    i += 1
print(total)

break 和 continue

如果循环条件为真,程序则会一直被困在这个循环体里。break(打破)则可以跳出这个循环体,而 continue 则是跳过接下来的语句,但是跳不出这个循环。

while True:
    print("in")
    break
print("out")

while True:
    print("in")
    continue
    print("ininin")
print("out")