编程语言
首页 > 编程语言> > 【Python】8.有益的探索

【Python】8.有益的探索

作者:互联网

一、概述

尝试着潜入水中,往冰山的深处扎一个小小的猛子

二、数据类型底层实现

1. 从奇怪的列表说起

1.1 错综复杂的复制

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}]
# list_3 = list_1          # 错误!!!
list_2 = list_1.copy()     # 或者list_1[:] \ list(list_1) 均可实习浅拷贝

输入:

list_2[1].append(55)

print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [1, [22, 33, 44, 55], (5, 6, 7), {'name': 'Sarah'}]
list_2:   [1, [22, 33, 44, 55], (5, 6, 7), {'name': 'Sarah'}]

1.2 列表的底层实现

引用数组的概念

列表内的元素可以分散的存储在内存中

列表存储的,实际上是这些元素的地址!!!——地址的存储在内存中是连续的

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}]
list_2 = list(list_1)   # 浅拷贝   与list_1.copy()功能一样

(1)新增元素

输入:

list_1.append(100)
list_2.append("n")
 
print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [1, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 100]
list_2:   [1, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 'n']

(2)修改元素

输入:

list_1[0] = 10
list_2[0] = 20

print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [10, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 100]
list_2:   [20, [22, 33, 44], (5, 6, 7), {'name': 'Sarah'}, 'n']

(3)对列表型元素进行操作 

输入:

list_1[1].remove(44)
list_2[1] += [55, 66]

print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [10, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah'}, 100]
list_2:   [20, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah'}, 'n']

(4)对元组型元素进行操作

元组是不可变的

输入:

list_2[2] += (8,9)

print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [10, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah'}, 100]
list_2:   [20, [22, 33, 55, 66], (5, 6, 7, 8, 9), {'name': 'Sarah'}, 'n']

(5)对字典型元素进行操作

输入:

list_1[-2]["age"] = 18

print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [10, [22, 33, 55, 66], (5, 6, 7), {'name': 'Sarah', 'age': 18}, 100]
list_2:   [20, [22, 33, 55, 66], (5, 6, 7, 8, 9), {'name': 'Sarah', 'age': 18}, 'n']

1.3 引入深拷贝

浅拷贝之后

引入深拷贝

输入:

import copy

list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}]
list_2 = copy.deepcopy(list_1)
list_1[-1]["age"] = 18
list_2[1].append(55)

print("list_1:  ", list_1)
print("list_2:  ", list_2)

输出:

list_1:   [1, [22, 33, 44], (5, 6, 7), {'name': 'Sarah', 'age': 18}]
list_2:   [1, [22, 33, 44, 55], (5, 6, 7), {'name': 'Sarah'}]

2. 神秘的字典

2.1 快速的查找

输入:

import time

ls_1 = list(range(1000000))
ls_2 = list(range(500))+[-10]*5000

start = time.time()
count = 0
for n in ls_2:
    if n in ls_1:
        count += 1
end = time.time()
print("查找{}个元素,在ls_1列表中的有{}个,共用时{}秒".format(len(ls_2), count,round((end-start),2)))

输出:

查找5500个元素,在ls_1列表中的有500个,共用时39.54秒

输入:

import time

d = {i:i for i in range(100000)}
# print(d)
ls_2 = list(range(500))+[-10]*5000

start = time.time()
count = 0
for n in ls_2:
    try:
        d[n]
    except: 
        pass
    else:
        count += 1
end = time.time()
print("查找{}个元素,在ls_1列表中的有{}个,共用时{}秒".format(len(ls_2), count,round(end-start)))

输出:

查找5500个元素,在ls_1列表中的有500个,共用时0秒

2.2 字典的底层实现

通过稀疏数组来实现值的存储与访问

字典的创建过程

d = {}

输入:

print(hash("python"))
print(hash(1024))
print(hash((1,2)))

输出:

-1700689346824694673
1024
-3550055125485641917

输入:

d["age"] = 18    # 增加键值对的操作,首先会计算键的散列值hash("age")
print(hash("age")) 

输出:

3061355840583939350

极个别时候,散列值会发生冲突,则内部有相应的解决冲突的办法

for i in range(2, 2):
    print(i)

键值对的访问过程

d["age"]

      如果存在,则返回该值  
      如果不存在,则报错KeyError

2.3 小结

(1)字典数据类型,通过空间换时间,实现了快速的数据查找

(2)因为散列值对应位置的顺序与键在字典中显示的顺序可能不同,因此表现出来字典是无序的

3. 紧凑的字符串

通过紧凑数组实现字符串的存储

4. 是否可变

4.1 不可变类型:数字、字符串、元组

在生命周期中保持内容不变

输入:

x = 1
y = "Python"

print("x id:", id(x))
print("y id:", id(y))

输出:

x id: 140718440616768
y id: 2040939892664

输入:

x += 2
y += "3.7"

print("x id:", id(x))
print("y id:", id(y))

输出:

x id: 140718440616832
y id: 2040992707056

元组并不是总是不可变的

当原组中是不可变类型的元素时,原组才是不可变的

输入:

t = (1,[2])
t[1].append(3)

print(t)

输出:

(1, [2, 3])

4.2 可变类型:列表、字典、集合

输入:

ls = [1, 2, 3]
d = {"Name": "Sarah", "Age": 18}

print("ls id:", id(ls))
print("d id:", id(d))

输出:

ls id: 2040991750856
d id: 2040992761608

输入:

ls += [4, 5]
d_2 = {"Sex": "female"}
d.update(d_2)            # 把d_2 中的元素更新到d中

print("ls id:", id(ls))
print("d id:", id(d))

输出:

ls id: 2040991750856
d id: 2040992761608

5. 列表操作的几个小例子

【例1】 删除列表内的特定元素

缺点:每次存在运算,都要从头对列表进行遍历、查找、效率低

输入:

alist = ["d", "d", "d", "2", "2", "d" ,"d", "4"]
s = "d"
while True:
    if s in alist:
        alist.remove(s)
    else:
        break
print(alist)

输出:

['2', '2', '4']

输入:

alist = ["d", "d", "d", "2", "2", "d" ,"d", "4"]
for s in alist:
    if s == "d":
        alist.remove(s)      # remove(s) 删除列表中第一次出现的该元素
print(alist)

输出:

['2', '2', 'd', 'd', '4']

解决方法:使用负向索引

输入:

alist = ["d", "d", "d", "2", "2", "d" ,"d", "4"]
for i in range(-len(alist), 0):
    if alist[i] == "d":
        alist.remove(alist[i])      # remove(s) 删除列表中第一次出现的该元素
print(alist)

输出:

['2', '2', '4']

【例2】 多维列表的创建

输入:

ls = [[0]*10]*5
ls

输出:

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

输入:

ls[0][0] = 1
ls

输出:

[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

三、更简洁的语法

输入:

 

输出:

 

 

四、三大神器

输入:

 

 输出:

 

 

五、重难点回顾

输入:

 

 输出:

 

 

标签:Sarah,22,探索,Python,list,有益,ls,print,id
来源: https://blog.csdn.net/weixin_40633696/article/details/115726398