首页 > 编程语言 >第02天-python线性数据结构

第02天-python线性数据结构

时间:2023-02-09 01:44:43浏览次数:51  
标签:02 None python image 列表 索引 l3 print 数据结构


1、数值处理
1.1、内建常用数据类型
1.1.1、分类
数值型
   int、float、complex、bool
   
序列sequence
    字符串str、字节序列bytes、bytearray
    列表list、元组tuple
    
键值对
    集合set、字典dict
1.2、数值型
int、float、complex、bool都是class,1、5.0、2+3j都是对象即实例
int: python3的int就是长整型,且没有大小限制,受限于内存区域的大小
float: 由整数部分和小数部分组成。支持十进制和科学计数法表示。C的双精度型实现
complex: 有实数和虚数部分组成,实数和虚数部分都是浮点数,3+4.2J
bool: int的子类,仅有2个实例True、False对应1和0,可以和整数直接运
      True=1和False=0为int的子类
1.2.1、bool: int的子类
bool(''), int(float('1.2'))         ------>float转换的问题
(False, 1)
1.2.1.1、int + bool 隐式类型转换
123 + True , 123 + False       -----> int + bool  > int + int 隐式类型转换
(124, 123)

123 + False  + 1.2    ----> int + bool + float => float 一定有隐式类型转换,仅仅限于数值计算中
124.2

 


1.2.1.2、强制类型转换
int(123 + False  + 1.2) 
124

 
image-20210825233546600
1.2.2、类型转换int_float_bool
int、float、complex、bool也可以当做内建函数对数据进行类型转换
int(x) 返回一个整数
float(x) 返回一个浮点数
complex(x)、complex(x,y) 返回一个复数
bool(x) 返回布尔值,前面讲过False等价的对象
1.2.3、整除
math模块的floor()、ceil()函数; 内建函数int()、round(); 运算符//
# 整除
print(3//2, 5//2, 7//2)
print(-3//2, -5//2, -7//2)
print(7//2, 7//-2, -7//2, -(7//2))

# int
print('int ------------')
print(int(1.4), int(1.5), int(1.6))
print(int(-1.4), int(-1.5), int(-1.6))

# ceil floor
print('ceil floor ------------')
import math
print(math.floor(2.5), math.floor(-2.5))
print(math.ceil(2.5), math.ceil(-2.5))

# round
print('round ------------')
print(round(1.4), round(-1.4), round(-1.6), round(1.6))
print(round(2.4), round(-2.4), round(2.6), round(2.6))
print('round .5 ---------')
print(round(0.5), round(1.5), round(2.5), round(3.5))
print(round(-0.5), round(-1.5), round(-2.5), round(-3.5))

round(),四舍六入五取偶
math.floor()向下取整
math.ceil()向上取整
int() 取整数部分
// 整除且向下取整
1.2.3.1、向下取正符号//
math.floor()向下取整

# //                                       ------->向下取整
1//2,  2//2, 3//2, 4//2, 5//2,
(0, 1, 1, 2, 2)                            ------->计算后变成元组

# //
-1//2,  -2//2, -3//2, -4//2, -5//2,        ------->向下取整
(-1, -1, -2, -2, -3)

 


1.2.3.2、math.floor()向下取整
for i in (0, 0.5,1,1.2,1,5,1.7,2,2.1,2.5,2.8):     #元组,可以迭代对象
    print(i,math.floor(i))     #向下
0 0
0.5 0
1 1
1.2 1
1 1
5 5
1.7 1
2 2
2.1 2
2.5 2
2.8 2

for i in (0, 0.5,1,1.2,1,5,1.7,2,2.1,2.5,2.8): 
    print(-i,math.floor(-i))   #向下
0 0
-0.5 -1
-1 -1
-1.2 -2
-1 -1
-5 -5
-1.7 -2
-2 -2
-2.1 -3
-2.5 -3
-2.8 -3

 


1.2.3.3、math.ceil()向上取整
for i in (0, 0.5,1,1.2,1,5,1.7,2,2.1,2.5,2.8): 
    print(-i,math.ceil(-i))
0 0
-0.5 0
-1 -1
-1.2 -1
-1 -1
-5 -5
-1.7 -1
-2 -2
-2.1 -2
-2.5 -2
-2.8 -2

 
image-20210825213314777
1.2.3.4、int截取整数部分
for i in (0.0, 0.5,1.0,1.2,1.5,1.7,2.0,2.1,2.5,2.8): 
    print(i,int(i))
0.0 0
0.5 0
1.0 1
1.2 1
1.5 1
1.7 1
2.0 2
2.1 2
2.5 2
2.8 2

 
image-20210825214109025
1.2.3.4.1、int截取整数部分
for i in (0.0, 0.5,1.0,1.2,1.5,1.7,2.0,2.1,2.5,2.8): 
    print(-i,int(-i))            # int 转换为整型,复数,向上, int截取整数部分// floor;ceil
-0.0 0
-0.5 0
-1.0 -1
-1.2 -1
-1.5 -1
-1.7 -1
-2.0 -2
-2.1 -2
-2.5 -2
-2.8 -2

for i in (0.0, 0.5,1.0,1.2,1.5,1.7,2.0,2.1,2.5,2.8): 
    print("{}\t{}".format(-i,int(-i)))           #取间隔相同
-0.0    0
-0.5    0
-1.0    -1
-1.2    -1
-1.5    -1
-1.7    -1
-2.0    -2
-2.1    -2
-2.5    -2
-2.8    -2

 


1.2.3.5、round(),四舍六入五取偶
1.2.3.5.1、四舍六入取整
for i in (0.0,1.2,1.7,2.0,2.1,2.8):
    print("{}\t{}".format(i,round(i)))
0.0 0
1.2 1
1.7 2
2.0 2
2.1 2
2.8 3

 
image-20210825215400506
1.2.3.5.2、四舍六入取整
for i in (0.0,1.2,1.7,2.0,2.1,2.8):
    print("{}\t{}".format(-i,round(-i)))
-0.0    0
-1.2    -1
-1.7    -2
-2.0    -2
-2.1    -2
-2.8    -3

for i in (0.5,1.5,2,5,3.5,-0.5,-1.5,-2.5,-3.5):
    print("{}\t{}".format(-i,int(-i)))
-0.5    0
-1.5    -1
-2  -2
-5  -5
-3.5    -3
0.5 0
1.5 1     
2.5 2
3.5 3

 
image-20210825220610555
1.2.4、常用数值处理函数
min()、max()
pow(x,y) 等于 x**y
math.sqrt() 等于 x ** 0.5
进制函数,返回值是字符串
    bin()、oct()、hex()
    
math模块
    math.pi π
    math.e 自如常数
    math模块中还有对数函数、三角函数等
1.2.4.1、min()、max()取最大最小
min(1,2,0), max(1,3,7,0)
(0, 7)

max?                 ----->查看解释
Docstring:
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value

With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
Type:      builtin_function_or_method

 
image-20210825230605489
1.2.4.2、pow(x,y) 等于 x**y多少次方
2**3, pow(2,3),math.pow(2,3)     ---->2的多少次方
(8, 8, 8.0)

 
image-20210825231005618
1.2.4.2.1、math.pow(,)开方
2**0.5,math.pow(2,0.5)        ---->2的多少次方
(1.4142135623730951, 1.4142135623730951)
1.2.4.3、bin()输出字符串类型值
bin(10)          ----->#输出为二进制字符串类型值
'0b1010'

 
image-20210825231827256
1.2.4.4、hex(*) 十六进制输出
hex(10)        ----->#输出为十六进制字符串类型值
'0b1010'
1.2.4.5、oct()八进制输出
oct(10)       ----->#输出为八进制字符串类型值
'0o12'
1.2.4.5.1、八进制运算
0o12 + 1     ---->十进制变为二进制后运算,结果为10进制
11
2、线性表原理和列表1
 线性表:
    线性表(简称表),是一种抽象的数学概念,是一组元素的序列的抽象,它由有穷个元素组成(0
    个或任意个)
    顺序表: 使用一大块连续的内存顺序存储表中的元素,这样实现的表称为顺序表,或称连续表
    在顺序表中,元素的关系使用顺序表的存储顺序自然地表示
    链接表: 在存储空间中将分散存储的元素链接起来,这种实现称为链接表,简称链表
    
列表如同地铁站排好的队伍,有序,可以插队、离队,可以索引。

链表如同操场上手拉手的小朋友,有序但排列随意。或者可以想象成一串带线的珠子,随意盘放在桌
上。也可以离队、插队,也可以索引。

对比体会一下,这两种数据结构的增删改查。
2.1、单向列表查询

 
image-20210826111032712
2.2、链接表
链接表: 在存储空间中将分散存储的元素链接起来,这种实现称为链接表,简称链表

 
image-20210826112211301
2.3、顺序表
顺序表: 
使用一大块连续的内存顺序存储表中的元素,这样实现的表称为顺序表,或称连续表在顺序表中,元素的关系使用顺序表的存储顺序自然地表示

 
image-20210826113054870
2.4、列表list
一个排列整齐的队伍,Python采用顺序表实现
列表内的个体称作元素,由若干元素组成列表
元素可以是任意对象(数字、字符串、对象、列表等)
列表内元素有顺序,可以使用索引
线性的数据结构
使用 [ ] 表示
列表是可变的       ----->数据类型,可变也不可变

列表是非常重要的数据结构,对其内存结构和操作方法必须烂熟于心。
2.4.1、列表显示
[], list()
([], [])

[], list(), [1],[1,2],[1,2,'a','222',True,None,[3,4]]
([], [], [1], [1, 2], [1, 2, 'a', '222', True, None, [3, 4]])

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

list([1,2,3])
[1, 2, 3]


l1 = list(range(5))   #index索引
l1                               ----->赋值即定义
[0, 1, 2, 3, 4, 5]

l1[2]              #len(l1-1) 正负索引不可以超界,超界报indexError
2

l1[-1],l1[-5]     # [-len(l1), -1] ----->负索引,从后往前
(5, 1)

内建函数 
len()              ----->表示长度
l1 = [0,1,2,3,4,5]
len(l1)
6                  长度为6

 



 



 



 



 
image-20210831141539035
2.4.2、初始化
list() -> new empty list
list(iterable) -> new list initialized from iterable's items
[]
列表不能一开始就定义大小

ls1 = []
ls2 = list()
ls3 = [2, 'ab', [3, 'abc'], (5, 30, 50)] # 列表是一个容器,元素可以是其它类型
ls4 = list(range(5)) # 非常常用的构造方式,将一个可迭代对象转换为一个列表
2.4.3、索引
索引,也叫下标
正索引:从左至右,从0开始,为列表中每一个元素编号

    如果列表有元素,索引范围[0, 长度-1]
负索引:从右至左,从-1开始

    如果列表有元素,索引范围[-长度, -1]
正、负索引不可以超界,否则引发异常IndexError

为了理解方便,可以认为列表是从左至右排列的,左边是头部,右边是尾部,左边是下界,右边是上界
列表通过索引访问,list[index] ,index就是索引,使用中括号访问

使用索引定位访问元素的时间复杂度为indexO(one),这是最快的方式,是列表最好的使用方式。
                    时间复杂度越小,效率越高
2.4.4、查询
index(value,[start,[stop]])
    通过值value,从指定区间查找列表内的元素是否匹配
    匹配第一个就立即返回索引
    匹配不到,抛出异常ValueError
count(value)
    返回列表中匹配value的次数
时间复杂度
    index和count方法都是O(n)
    随着列表数据规模的增大,而效率下降
如何返回列表元素的个数?如何遍历?如何设计高效?
    len()
2.4.4.1、index()时间复杂度为大O(n)
index O(n) #随着规模n增加 耗时 增加
l1.index(4),l1.index(3)
(4, 3)

l1.index(4)
4

l2 = [0,1,2,1,3,4]
l2.index(1),l2.index(1,1),l2.index(1,2)   从1开始往后找1,从2开始往后找1
(1, 1, 3)         索引值

l2.index(1),l2.index(1,1),l2.index(1,2,-1)
(1, 1, 3)         索引值

l2.index(4,2),l2.index(4,3)    从2开始找4,从3开始找4
(5, 5)            索引值  


index和 count 列表的方法效率如何?
count 遍历所有,O(n)
index O(n) #随着规模n增加 耗时 增加
len(l1)  #效率高吗? 非常高 存我们班进入一个人计数器+1,离开一个计数器-1,列表是封装对象,这个对象有自己的元数据,长度时间复杂度为大O(1)

 



 



 
image-20210831150418421
2.4.4.2、len时间复杂度为大O(1)
len时间复杂度为大O(1),时间复杂度越小,效率越高
l2 = [0,1,2,3,4]
len(l2)
6

 
image-20210831152118272
2.4.4.3、count时间复杂度为大O(1)
count O(n) #随着规模n增加 耗时 增加
l2 = [0,1,2,3,4]
l2.count(5),l2.count(4),l2.count(1)   5的索引总数为0,4的索引总数为1,1的索引总数为2
(0, 1, 2)

count时间复杂度为大O(1)

 
image-20210831150933994
2.4.5、修改
索引定位元素,然后修改。注意索引不能超界
ls1 = [1,2,3,4]
ls1[2] = 200
3、列表2和内存原理
3.1、增加单个元素
append(object) -> None
    列表尾部追加元素,返回None
    返回None就意味着没有新的列表产生,就地修改
    定位时间复杂度是O(1)
    
insert(index, object) -> None
    在指定的索引index处插入元素object
    返回None就意味着没有新的列表产生,就地修改
    定位时间复杂度是O(1)
    
索引能超上下界吗? 
    超越上界,尾部追加
    超越下界,头部追加
3.1.1、修改索引值
l2 = [0,1,2,1,3,4]

l2[-1]  = 2 

l2[-6] = [1,2]    ------>  从后往前索引第6位,[1,2]作为一个整体作为一个元素
l2
[[1, 2], 1, 2, 1, 3, 2]

l2,len(l2)        ------> l2的长度为6
([[1, 2], 1, 2, 1, 3, 2], 6)

len(l2)
6

l2[-1]  = 2         -----> 修改从后往前的第一个值为2
l2
[[1, 2], 1, 2, 1, 3, 2]

 



 
image-20210831160941165
3.1.2、append末追加索引值,效率高
l3.append(None)  #append 内部的最后加一个,效率好吗? 定位快,写操作比读操作慢。大O(1)
扩容问题: 另选地址,实现扩容
l3 = [1,2,3]    ----->追加索引4
l3.append(4)    
l3
[1, 2, 3, 4]
 
l3.append(6)       ------->追加索引6
l3
[1, 2, 3, 4, 5, 6]

 


3.1.3、insert中插入索引值,效率低
insert效率高吗?  少用,效率低
l3 = [1,2,3,4,5]
l3.append(None)
l3
[1, 2, 3, 4, 5, None]

l3.insert(-3,9)        ------>在倒数第三个中加9  
l3
[1, 2, 3, 9, 4, 5, None]

l3.insert(4,10)        ------>在正数第4个索引加10 
l3
[1, 2, 3, 9, 10, 4, 5, None]

l3.insert(0,'begin')  ------->在0索引处加一个'begin'
l3
['begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7]

l3.insert(-100,'left')  # insert函数返回值为None。浙往往说明该方法是就地修改
l3  
['left', 'begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7]

l3.insert(100,'right')    ---->在索引100后面添加'right'    #相当于append效率,效率不错
l3
['left', 'begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right']

#insert效率高吗? 一般来讲都不高insert(-1,xxx)中间插入,会引起其后所有的挪动

 
image-20210831170424824

 
image-20210831171000120

 
image-20210831171139948
3.2、增加多个元素
extend(iteratable) -> None
    将可迭代对象的元素追加进来,返回None
    就地修改,本列表自身扩展
    
+ -> list
    连接操作,将两个列表连接起来,产生新的列表,原列表不变
    本质上调用的是魔术方法__add__()方法
    
* -> list
    重复操作,将本列表元素重复n次,返回新的列表
    
ls1 = [1] * 5
ls2 = [None] * 6
ls3 = [1,2] * 3
ls4 = [[1]] * 3

这个重复操作看似好用,如果原理掌握不好,但非常危险
x = [1] * 3
x[0] = 100
print(x) # 结果是什么
3.2.1、extend
l3.extend([1,2,3])     ---->同时追加多个元素,[1,2,3]
l3
['left', 'begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right', 1, 2, 3]


l3.extend(range(5,8))   ---->range(5,8)添加一个取值范围,前包后不包,添加5,6,7
l3
['left', 'begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right', 1, 2, 3, 5, 6, 7]


l2 + [5, 6, 7]               ----->相加增加新的列表,但l2原来的值保持不变
[[1, 2], 1, 2, 1, 3, 2, 5, 6, 7]
l2
[[1, 2], 1, 2, 1, 3, 2]


l6


 
image-20210831172616552

 
image-20210831172849717

 
image-20210831173222665
3.2.2、将列表中的元素重复n回,装成一个新列表
l4 = [1,2]              ----->将列表中的元素重复3回,装成一个新列表
l4*5
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]

[1]*3,[None]*3,[0]*5    ------>将列表中的元素重复指定回,装成一个元素
([1, 1, 1], [None, None, None], [0, 0, 0, 0, 0])

 
image-20210831232723795
3.2.3、修改索引值
l5 = [1]*3      ------>将1这个元素重复多回,放入一个列表里面
l5 
[1,1,1]

l5[1] = 200     ------->修改l5中索引为1的改为200
l5     #[1,200,1]
[1, 200, 1]


l6 = [[1]]*3    ------->将[1]重复3次
l6
[[1], [1], [1]]

l6[1] = 300         ----->修改l6中索引1的元素为300
[[1], 300, [1]]

l6[0][0] = 500
[[500], 300, [500]] 

l5 = [1]*3 #[1,1,1]
l5[1] = 200 # [1,200,1]

l6 = [[1]] *3   # [[1],[1],[1]]      ------>类比
l6[1] =300      # [[1],300,[1]]      ----- >索引1的位置被替换为300
l6[0][0] = 500  # [[500],300,[500]]   l6[0]  => [1][0]  = 500  => [[500],300,[500]]
                          ------>索引0所对应的值为[1]被替换等于[500],后面的[1]替换为[500]
print(l6)
[[500], 300, [500]]

300 'abc' 字面长量,简单类型,可以错误认为他们放在列表里面就是自己的值    ---->传值
l6[1] = 'absdsfcks' 复杂类型,都是引用类型,都是放地址,传地址            ---->传地址

在Python中一切皆对象,而对象都是引用类型,可以理解为一个地址指针指向这个对象。
但是,字面常量字符串、数值等表现却不像引用类型,暂时可以称为简单类型。
而列表、元组、字典,包括以后学习的类和实例都可以认为是引用类型。
你可以认为简单类型直接存在列表中,而引入类型只是把引用地址存在了列表中。 

 



 



 
image-20210901154004723

 
image-20210902001525529

 
image-20210902002433163
4、列表3和深浅复制
4.1、删除三种方法
remove(value) -> None
    从左至右查找第一个匹配value的值,找到就移除该元素,并返回None,否则ValueError
    就地修改
    效率?                        ----->删除0,判断0是否在再表中
pop([index]) -> item
    不指定索引index,就从列表尾部弹出一个元素
    指定索引index,就从索引处弹出一个元素,索引超界抛出IndexError错误
    效率?指定索引的的时间复杂度?不指定索引呢?
clear() -> None
    清除列表所有元素,剩下一个空列表
4.1.1、remove效率低
l6.remove(0)  #效率高吗?非常低,找0 value得遍历。没找到还要抛异常ValueError,找到了,还要拿走,都会引起其后元素得挪动

l6
[[500], 300, [500]]

l6.remove(300)
l6
[[500], [500]]

remove: 用遍历来找值,大O(n),效率低下

 
image-20210902003703009

 
image-20210902094654911
4.1.2、pop效率高
l6
[[500], [500]]

l6.pop()        ------->删除一个值[500]
[500]

l6.pop()        ------->再删除一个值[500]
[500]
 
l6              ------->显示为空
[]

l3
['begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right', 1, 2, 3, 5, 6, 7]
l3.pop()        ------->pop弹出索引中的7
7
l3              ------->显示删除结果中的7
['begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right', 1, 2, 3, 5, 6]


l3       
['begin', 1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right', 1, 2, 3, 5, 6]
l3.pop()        -------->从后往前弹出
6
l3.pop(0)       -------->删除索引0对应的值begin
'begin'
l3
[1, 2, 3, 4, 10, 5, 9, None, 8, 7, 'right', 1, 2, 3, 5]


# 效率高吗?
# 一般不超界情况,比remove高,不用编历,给定index,定位数据快
# 如果不是末尾弹出的话,remove和pop从移除数据来讲都一样,拿走数据,后面的数据挪动
# 建议,列表来说,末尾移除倒数第一个元素,代价最小
列表使用:
append #追加、pop(-1) #删除元素、l1(index) #查看索引、len(l1) #索引长、l1[index] = 200, extend(range(5))  #同时追加多个元素

 
image-20210902095506088

 
image-20210902100529151

 
image-20210902101241065
4.1.3、clear 清除
    清除列表所有元素,剩下一个空列表
clear 1000个元素,你说不要就不要了? 从慢的要死磁盘搬来了1000个数据
4.2、reverse反转效率低
reverse() -> None
    将列表元素反转,返回None
    就地修改
这个方法最好不用,可以倒着读取,都不要反转。

l3.reverse()         ----->数据值反转                   ----->第1种反转
for x  in l3:         
    print(x)
5
3
2
1
right
7
8
None
9
5
10
4
3
2
1

l3
[5, 3, 2, 1, 'right', 7, 8, None, 9, 5, 10, 4, 3, 2, 1]
for index in range(1, len(l3)+1):         len前包后不包,索引index取反    ----->第2种反转
    print(l3[-index])
1
2
3
4
10
5
9
None
8
7
right
1
2
3
5

l3
[5, 3, 2, 1, 'right', 7, 8, None, 9, 5, 10, 4, 3, 2, 1]
for index  in range(len(l3)-1,-1,-1):     #索引到-1,每次递减1,输出索引    ----->第3种反转
    print(l3[index])
1
2
3
4
10
5
9
None
8
7
right
1
2
3
5

 
image-20210902110144691

 
image-20210902111842619

 
image-20210902112437918
4.3、sort就地排序效率低
sort(key=None, reverse=False) -> None
    对列表元素进行排序,就地修改,默认升序
    reverse为True,反转,降序
    key一个函数,指定key如何排序,lst.sort(key=function)
如果排序是必须的,那么排序。排序效率高吗?

l5 = [1,200,1]
l5
[1, 200, 1]

l5.sort()                ------>就地排序
l5
[1, 1, 200]

l5.sort(reverse=True)    ------>反转后面的值
l5
[200, 1, 1]

l3
[5, 3, 2, 1, 'right', 7, 8, None, 9, 5, 10, 4, 3, 2, 1]
l3.sort(key=str)  #key 但不影响输出结果中的值
l3                       ------>把里面所有元素变成str来比较,输出还是原值输出,不影响输出结果
                                排定座次,不影响输出结果
[1, 1, 10, 2, 2, 3, 3, 4, 5, 5, 7, 8, 9, None, 'right']

l3  #效率高吗? 不但遍历,而且大多数排序算法遍历n次-O(n*n)
# 冒泡法,插入排序,选择排序,堆排序,快速排序O 高效率O(1)
遍历时间复杂度是大O(n)

 
image-20210902132601356

 
image-20210902132911582

 
image-20210902133555766
4.4、in成员比较是否相等
'a' in ['a', 'b', 'c']
True

[3,4] in [1, 2, 3, [3,4]]      ---->先比较类型,在比较类容,比顺序
True

for x in [1,2,3,4]:
    pass
  
 
4.5、列表复制
列表复制
a = list(range(4))
b = list(range(4))
print(a == b)
c = a
c[2] = 10
print(a)
print(a == b) # 还相等吗?
print(a == c) # 相等吗?
4.5.1、列表复制示例
l7 = list(range(5))              ----->数据类型和数据都相等
l8 = list(range(5))
print(l7 == l8)
True

l7 = list(range(5))
l8 = list(range(5))
print(l7 == l8)        #  ==内容是否相等, 'a' == 1 首先比较类型,在比较内容,注意有序
x = l7 
x[2] = 100 
print(x == l7)    #等吗? --时,先判断内存地址如果相等,直接返回True,如果不相等,再比较内容
True
True

l7 = list(range(5))
l8 = list(range(5))
print(l7 == l8)
x = l7 
x[2] = 100 
print(x == l7)
print(x == l8)
True
True
False

 
image-20210902172442039

 
image-20210902173201642

 
image-20210902211340195
4.5.2、列表的内存模型和深浅拷贝
# copy
l9 = list(range(5))
l10 = l9.copy()       ----->复制,产生了一个人全新的副本
print(l9 == l10)
l9[1] = 100
print(l9 == l10)
print(l9,l10)
True
False
[0, 100, 2, 3, 4] [0, 1, 2, 3, 4]

l11 = [1,[2,3,4],[5]]       # [1,A1,5] ------>浅拷贝,根本不跟踪到地址内部称为浅拷贝,影子拷贝
l12 = l11.copy()             # [1,A1,5] ------>l11与l12打印出来的值一样,
print(1,l11 == l12)
l12[1][1] = 300
print(2,l11 == l12)
print(l11[1],id(l11[1]))
print(l12[1],id(l12[1]))
1 True
2 True
[2, 300, 4] 2127183061448    ------>地址相同,浅拷贝
[2, 300, 4] 2127183061448    ------>地址相同,浅拷贝

l11 = [1,[2,3,4],[5]]        #[1,A1,5] [1,[2,3,4],5]
l12 = copy.deepcopy(l11)     #[1,A2,5] [1,[2,3,4],5]
print(1,l11 == l12)
print(l11,l12)
l12[1][1] = 300
print(2,l11 == l12)
print(l11,l12)
print(l11[1],id(l11[1]))        ------>地址不同,深拷贝
print(l12[1],id(l12[1]))        ------>地址不同,深拷贝
1 True
[1, [2, 3, 4], [5]] [1, [2, 3, 4], [5]]
2 False
[1, [2, 3, 4], [5]] [1, [2, 300, 4], [5]]
[2, 3, 4] 2127182488968  
[2, 300, 4] 2127183020232


大多使用的深拷贝

 
image-20210902212540032

 
image-20210902214009076

 
image-20210902214907111
4.6、Python内存管理(面试)
面试题。
    变量无须事先声明,也不需要指定类型,这是动态语言的特性
    变量只是一个标识符,指向一个对象,而这个对象被创建在内存"堆"中
    Python编程中一般无须关心变量的存亡,一般也不用关心内存的管理
    python使用引用计数记录所有对象的引用数。当对象引用数变为0,它就可以被 垃圾回收GC
计数增加:
    赋值给其它变量就增加引用计数,例如x=3; y=x; z=[x, 1]
    实参传参,如foo(y)
计数减少:
    函数运行结束时,局部变量就会被自动销毁,对象引用计数减少
    
有关性能的时候,就需要考虑变量的引用问题,但是,到底该释放内存还是尽量不释放内存,看需求。
    内存是宝贵的,因为它快。但再好的硬件资源,再多的机器,在高并发面前都嫌少。内存一定要
    合理利用。
    但是,数据搬到内存中不易,不要把大量数据好不容易搬到内存中,立刻就不要了。这非常没有
    效率。
 stop  word

 
image-20210902225243475
4.6.1、引用计数的问题
标识垃圾的方法
引用计数是简单实现垃圾标记的办法。
引用计数可能出现循环引用,Python提供了gc模块,解决了这个问题。

import sys
#x = []
#print(sys.getrefcount(x))
#y = x
#print(sys.getrefcount(y))
#z = y
#print(sys.getrefcount(x))

z = 1   #字面常量
print(sys.getrefcount(z))
x = 1
y = 1
print(sys.getrefcount(x))

93
95

 
image-20210902231453433
5、随机数元组字符串
5.1、随机数
随机数
random模块
    randint(a, b) 返回[a, b]之间的整数
    randrange ([start,] stop [,step]) 从指定范围内,按指定基数递增的集合中获取一个随机数,基数
缺省值为1。 random.randrange(1,7,2)
    choice(seq) 从非空序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。random.choice([1,3,5,7])
    3.6开始提供choices,一次从样本中随机选择几个,可重复选择,可以指定权重
    random.shuffle(list) ->None 就地打乱列表元素
    sample(population, k) 从样本空间或总体(序列或者集合类型)中随机取出k个不同的元素,返回一个新的列表
    
    random.sample(['a', 'b', 'c', 'd'], 2)
    random.sample(['a', 'a'], 2) 会返回什么结果
    每次从样本空间采样,在这一次中不可以重复抽取同一个元素
    
import random
for i in range(5):
    print(random.randint(1,2))        ------>(1,2)随机的整数
2
1
1
2
2

 
image-20210903090634524
5.1.1、choices选择随机数
x = [1,2,3,4,5]
for i in range(5):
    print(random.choice(x))    ---->拿5次数据,每次都从x中任意抽取一个元素
5
2
5
4
2

random.shuffle(x)     ----->随机打乱数据
x
[1, 2, 4, 5, 3]


for i in range(5):
    print(random.choices(x))   #取一下,等价为choice,返回值不同,默认k=1
[4]
[4]
[4]
[2]
[2]

for i in range(5):
    print(random.choices(x,k=2))   #取一下,等价为choice,返回值不同,k=2可以重复的取2下
[5, 3]
[3, 4]
[5, 5]
[5, 5]
[3, 4]

for i in range(5):
    print(random.choices([0,1],k=6))     ------>在[0,1]列表中,随机取6次
[1, 1, 1, 1, 1, 1]
[1, 0, 1, 0, 1, 0]
[1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 1]
[1, 0, 1, 1, 1, 0]

for i in range(5):
    print(random.choices([0,1],[10,1],k=6))     ---->在列表[0,1]按照10:1的量来取6个值
[0, 1, 0, 1, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 1, 0]
[0, 0, 0, 0, 0, 0]
[0, 1, 0, 1, 1, 0]

 
image-20210903091247320

 
image-20210903093326675

 
image-20210903094037519

 
image-20210903095158516

 
image-20210903095505955
5.1.2、sample不重复拿数据
print(x)
print('***************')
for i in range(5):
    print(random.sample(x, k=5))  --->不重复拿,每一个索引的元素拿一次
[1, 2, 4, 5, 3]
***************
[1, 4, 3, 2, 5]
[5, 4, 2, 1, 3]
[3, 5, 1, 4, 2]
[2, 1, 5, 4, 3]
[4, 3, 5, 1, 2]   

x = [1,1,1,1,1]
print(x)
print('***************')
for i in range(5):
    print(random.sample(x, k=5))    ----->分别在不同的索引上的1 ,k的值不能大于索引的值
[1, 1, 1, 1, 1]
***************
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]

 
image-20210903100546396

 
image-20210903105730298
5.2、元组tuple
5.2.1、初始化
t1 = () # 空元组
t2 = (1,) # 必须有这个逗号
t3 = (1,) * 5
t4 = (1, 2, 3)
t5 = 1, 'a'
t6 = (1, 2, 3, 1, 2, 3)
t7 = tuple() # 空元组
t8 = tuple(range(5))
t9 = tuple([1,2,3])
5.2.2、元组的定义与使用
一个有序的元素组成的集合
使用小括号 ( ) 表示
元组是不可变对象

1,2
(1, 2)

(), tuple(),(1,)  ---->两个空元组
((), (), (1,))

t1 = (), tuple(),(1,)   ----->两个空元组,和有一个元素的元组,一个大元组的三个元素
t1
((), (), (1,))

t1 = (), tuple(),(1,)   
t1
((), (), (1,)) 
t1, type(t1)
(((), (), (1,)), tuple)       ----->元素类型为空元组

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


t2 = (0,1,2,3,4,5)
t2.index(1) ,  1 in t2,  5 in t2 , 6 in t2 ,t2.count(2),len(t2)  ------>1,2,5,6元素是否在t2中,in作为判断 , count(2)遍历元素2出现的次数为1,  len(t2)元组的长度
(1, True, True, False, 1, 6)

t3 = (1,2)*3        ------>设置一个元组
t3
(1, 2, 1, 2, 1, 2) 
for x in t3:
    print(x)
1
2
1
2
1
2

t3[1] = 123         ------->次元组对象不可增删改,查可以
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-80-9f5045351df1> in <module>
----> 1 t3[1] = 123

TypeError: 'tuple' object does not support item assignment


t4 = ()
t4 = (1,[2,3,4],5)       ------>地址为A1没变,A1对应的列表中的值发生改变
t4[1][1] = 300
t4
(1, [2, 300, 4], 5)

t5 = (1,(2,3,4),5)      ------->此中间的(2,3,4)为元组所以,不能改元组
t5[1][1] = 200
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-87-a0d48b604633> in <module>
      1 t5 = (1,(2,3,4),5)
----> 2 t5[1][1] = 200

TypeError: 'tuple' object does not support item assignment

t6 = ([1],)*3      ------>[1]*3 [1,1,1] #([1],[1],[1]) #(A1,A1,A1)
t6[0] = 'abc'      
t6
([1], [1], [1])
t6[1][0] = 300 
t6
([300], [300], [300])

 
image-20210903110346584

 
image-20210903110600225

 
image-20210903111224486

 
image-20210903112035840

 
image-20210903112615514

 
image-20210903140529584

 
image-20210903140712657

 



 
image-20210903142335137

 
image-20210903142821493
5.3、字符串
一个个字符组成的有序的序列,是字符的集合
使用单引号、双引号、三引号引住的字符序列
字符串是不可变对象,是字面常量

Python3起,字符串都是Unicode类型
5.3.1、初始化
s1 = 'string'
s2 = "string2"
s3 = '''this's a "String" '''
s4 = 'hello \n zhgedu.com'
s5 = r"hello \n zhgedu.com"
s6 = 'c:\windows\nt'
s7 = R"c:\windows\nt"
s8 = 'c:\windows\\nt'
name = 'tom'; age = 20  # python代码写在一行,使用分号隔开,不推荐
s9 = f'{name}, {age}'   # 3.6支持f前缀
sql = """select * from user where name='tom' """

r前缀:所有字符都是本来的意思,没有转义
f前缀:3.6开始,使用变量插值

字符串不可修改

时间复杂度
find、index和count方法都是O(n)
随着字符串数据规模的增大,而效率下降

len(string)
返回字符串的长度,即字符的个数
5.3.2、字符串的使用
s1 = 'abc de f'
len(s1)
8

s2 = 'a\tb\nc'     ------->转移过后只有5个字符
print(len(s2)) 
5

s3 = r'a\tb\nc'     ------>添加r前缀后字符都是本来的意思,没有转意
print(len(s3)) 
7

for x in s1:
    print(x,type(x))
a <class 'str'>
b <class 'str'>
c <class 'str'>
  <class 'str'>
d <class 'str'>
e <class 'str'>
  <class 'str'>
f <class 'str'>

'a' + 'b'        ----->输出一个全新的对象
'ab'

s = 'a'               ------>对象的地址发生改变
print(s, id(s))
s +='b'  #s = s + 'b'
print(s,id(s))
s ='ab'
a 2012087083784
ab 2012166459776

s = 'a'
s1 = s *5
s1
'aaaaa'


''.join('abcd'), ",".join('abcd')        ---->把空串与'abcd'拼接在一起,相当于间隔符
('abcd', 'a,b,c,d')

 
image-20210903145101380

 
image-20210903145409801
5.3.2.1、map拼接字符串
",".join(map(str,range(5)))  #map(?,range(5))  ---->使用map拼接字符串
'0,1,2,3,4'

",".join(map(str,[1,'a',2]))      ----->map拼接字符串
'1,a,2'
5.3.2.2、find找字符串中元素位置
s.find('t'),s.find('www'),s.find('edu'),s.find('com',7)   
                               ----->找不到返回-1,找到返回>=0的索引
(-1, 0, 7, 11)

s.rfind('t'),s.rfind('www'),s.rfind('edu'),s.rfind('com',8)     
(-1, 0, 7, 11)                 ------>#大O(n) 遍历查找子串能少则少,rfind从左往右

s.index('www'),s.rfind('www') ,s.rindex('www') 
(0, 0, 0)                      ------># O(n),两个测试'www'是否存在  

s.count('www')      
1                              ------>'www'出现的次数
5.3.3、split分割字符串
"a \r\n\tb\tc\nd".split()   #遍历字符串,用尽可能长的空白字符作为分隔符, 一刀两断
['a', 'b', 'c', 'd']


"a \r\n\tb\tc\r\nd".split('\r\n')   ----->'\r\n'作为切割点
['a ', '\tb\tc', 'd']


"a \r\n\tb\tc\r\nd".split('\n')    ----->'\n'作为切割点
['a \r', '\tb\tc\r', 'd']


s3 = ','.join('abcd')             ----->maxsplit=2表示最多切两刀
s3.split()
['a,b,c,d']
s3.rsplit(',',maxsplit=2)    
['a,b', 'c', 'd']

"\r\na  \r\n\tb\nc\r\nd\r\n".splitlines()  ----->#line? 有换行符的给切掉
['', 'a  ', '\tb', 'c', 'd']

 
image-20210903160601410
5.3.3.1、partition切割符
s3 = ','.join('abcd')

s3.partition(',')   #3元组,split(',',1)
('a', ',', 'b,c,d')

s3.rpartition(',') #rsplit(',',1)
('a,b,c', ',', 'd')



s3.partition('.')   #3元组,split(',',1)
('a,b,c,d', '', '')

s3.rpartition('.') #rsplit(',',1)
('', '', 'a,b,c,d')

 
image-20210903164311896
5.3.4、replace替换
s3.replace(',','+++ ')   #返回一个全新字符串,把,号替换成'+++'
'a+++b+++c+++d'


s4 = 'www.zhgedu.com'              ------'ww'替换成一个w
print(s4.replace('w','w'))
print(s4.replace('ww','w'))
print(s4.replace('www','w'))
www.zhgedu.com
ww.zhgedu.com
w.zhgedu.com

 
image-20210903164728147

 
image-20210903165100321
5.3.5、strip移除
"\r\na   \r\n\tb\nc\rd\r\n".strip('\nd\r')      ----->移除\nd\r的值
'a   \r\n\tb\nc'

"\r\na   \r\n\tb\nc\rd\r\n".strip('a\n d\r') 
'\tb\nc'

 
image-20210903165727701

 
image-20210906091426762

 
image-20210906091732527
5.3.6、首尾判断
endswith(suffix[, start[, end]]) -> bool
    在指定的区间[start, end),字符串是否是suffix结尾
startswith(prefix[, start[, end]]) -> bool
    在指定的区间[start, end),字符串是否是prefix开头
    
    
s3.startswith('a,b')   ------>是不以'a,b'开头的
True


s3.startswith('a,b'),s3.endswith('d')    ------->是不以'd'结尾的
(True, True)



cmd = input('>>')                             ------->移除两边空格,字符串转小写
if cmd.strip().lower()=='nginx':   #Nginx,nginX
    print('yes')
else:
    print(cmd)
>>a
a

cmd = input('>>')                            ------->移除两边空格,字符串转小写
if cmd.strip().lower()=='nginx':   #nginx,nginx
    print('yes')
else:
    print(cmd)
>>nginx
yes
 
cmd = input('>>')                            ------->移除两边空格,字符串转小写
if cmd.strip().lower()=='nginx':   #nginx,nginx
    print('yes')
else:
    print(cmd)
>>NGinx
yes

 
image-20210906092459566

 
image-20210906092635564

 
image-20210906094320252
5.3.7、其它函数
其它函数
upper()大写
lower()小写
swapcase() 交换大小写
isalnum() -> bool 是否是字母和数字组成
isalpha() 是否是字母
isdecimal() 是否只包含十进制数字
isdigit() 是否全部数字(0~9)
isidentifier() 是不是字母和下划线开头,其他都是字母、数字、下划线
islower() 是否都是小写
isupper() 是否全部大写
isspace() 是否只包含空白字符
其他格式打印函数中文几乎不用,大家自行查看帮助

cmd = input('>>')                  ------>判断是否输入的数字或者字母
if cmd.strip().lower()=='nginx':   #nginx,nginx
    print('yes')
elif cmd.isalnum():
    print(cmd, 'alnum')
else:
    print(cmd)
>>aq1
aq1 alnum

cmd = input('>>')                      ------->输出第三个结果
if cmd.strip().lower()=='nginx':   #nginx,nginx
    print('yes')
elif cmd.isalnum():
    print(cmd, 'alnum')
else:
    print(cmd)
>>----
----

cmd = input('>>')                       ------->输出第一个结果
if cmd.strip().lower()=='nginx':   #nginx,nginx
    print('yes')
elif cmd.isalnum():
    print(cmd, 'alnum')
else:
    print(cmd)
>>nginx
yes

 
image-20210906110949033

 
image-20210906110903846
5.3.7.1、C风格printf-style
"I am %03d" % (20,)
'I like %s.' % 'Python'
"%3.2f%% 0x%x %#X" % (89.7654, 10, 256) # 宽度为3,小数点后2位
"I am %-5d" % (20,)
"%(host)s.%(domain)s" % {'domain':'magedu.com', 'host':'www'} # 靠名字对应


"I'm %s ." % (20)
"I'm 20 ."

"I'm %d years old." % (20)
"I'm 20 years old."

"I'm %s %s." % (20, 'years old')
"I'm 20 years old."

"%3.2f%%"  % 20.236
'20.24%'

宽度为3,小数点后2位
"%3.2f%% %s %s"  % (20.236,127,255)    
'20.24% 127 255'

靠名字对应
"%(host)s.%(domain)s" % {'domain':'zhgedu.com','host':'www'}  
'www.zhgedu.com'

 
image-20210906111039461

 
image-20210906113200890

 
image-20210906113806705
5.3.7.2、format函数
5.3.7.2.1、位置对应
位置对应
"I'm {} {}".format(20,'years old')           ------>互为相同
"I'm 20 years old"

"I'm {1} {0}".format('years old',20)         ------>互为相同,输入索引值
"I'm 20 years old"

位置或关键字对应
"{prefix} {1} {0}".format('years old',20,prefix="I'm")   ------>互为相同
"I'm 20 years old"

"{} {} {}".format("I'm", 20, 'years old')                ------>互为相同
"I'm 20 years old"

参数解构:
"I'm {} {}".format(*(20,'year lod'))     
"I'm 20 year lod"

进制:
"{0},{0:d},{0:#b},{0:o},{0:#X}".format(31)
'31,31,0b11111,37,0X1F'

 
image-20210906114107947

 
image-20210906114705822
5.3.7.2.2、浮点数宽度
# 浮点数
print("{}".format(3**0.5)) # 1.7320508075688772
print("{:f}".format(3**0.5)) # 1.732051,精度默认6
print("{:10f}".format(3**0.5)) # 右对齐,宽度10
print("{:2}".format(102.231)) # 宽度为2数字
print("{:2}".format(1)) # 宽度为2数字
print("{:.2}".format(3**0.5)) # 1.7 2个数字
print("{:.2f}".format(3**0.5)) # 1.73 小数点后2位
print("{:3.2f}".format(3**0.5)) # 1.73 宽度为3,小数点后2位
print("{:20.3f}".format(0.2745)) # 0.275
print("{:3.3%}".format(1/3)) # 33.333%
# 注意宽度可以被撑破

"{:10f}".format(3**0.5)      ----->右对齐,宽度为10 
'  1.732051'

print("{:2}".format(102.231))   ------>宽度为2的数字
102.231
print("{:20}".format(102.231))  ------>宽度为20的数字
            102.231
            
print("{:.2f}".format(3**0.5))  -------> 1.73小数点后2位
1.73

print("{:30.2f}".format(3**0.5)) -------> 1.73限制宽度为30,小数点后2位
                          1.73
print("{:30.2f}".format(0.2745)) -------> 1.73限制宽度为30,小数点后2位
                          0.27
                          
print("{:30.3%}".format(1/3)) # 33.333%     ------>小数点后三位,以%显示,宽度位30 
                       33.333%

 
image-20210907110107336

 
image-20210907110322781

 
image-20210907111121643
5.3.7.2.3、对齐
# 对齐
print("{}*{}={}".format(5, 6, 5*6))
print("{}*{}={:2}".format(5, 6, 5*6))
print("{1}*{0}={2:3}".format(5, 6, 5*6))
print("{1}*{0}={2:0>3}".format(5, 6, 5*6))
print("{}*{}={:#<3}".format(4, 5, 20))
print("{:#^7}".format('*' * 3))


print("{}*{}={}".format(5, 6, 5*6))
5*6=30

print("{}*{}={:20}".format(5, 6, 5*6))      ------>设置宽度为20
5*6=                  30

print("{1}*{0}={2:3}".format(5, 6, 5*6))    ------>宽度为3
6*5= 30

print("{1}*{0}={2:0>3}".format(5, 6, 5*6))   ----->右对齐
6*5=030

print("{1}*{0}={2:#<3}".format(5, 6, 5*6))   ------>左对齐
6*5=30#

print("{:#^7}".format('*' * 3))       ------>字符串 x 3 = *** ,要放到宽度为7的里面去,不足的地方补#号
##***##

print("{}*{}={:#<{}}".format(5, 6, 5*6,5))  
5*6=30###
print("{}*{}={:#<{}}".format(5, 6, 5*6,2))
5*6=30

 
image-20210907135905777

 
image-20210907140008020

标签:02,None,python,image,列表,索引,l3,print,数据结构
From: https://www.cnblogs.com/zikang/p/17103894.html

相关文章

  • 第03天-python字节序列字典
    1、字节序列和切片1.1、字节序列Python3引入两个新的类型bytes、bytearray。bytes不可变字节序列;bytearray是可变字节数组。字节的世界里面没有编码1.2、编码与解......
  • PyQt5-快速上手笔记-02
    状态栏状态栏是用来显示应用状态信息的组件fromPyQt5.QtWidgetsimportQMainWindowclassmyWidget(QMainWindow):def__init__(self):super().__init_......
  • Python,形参,实参,值传递,地址传递
    1.值传递在实参向形参传递的过程中,传递的只是实参的值,而在函数体操作的时候,实际操作的并不是实参而是形参,所以,值传递不改变原变量值。2.地址传递在实参向形参传递的过程中......
  • Python mock
    官方链接:https://docs.python.org/zh-cn/3/library/unittest.mock-examples.htmlMock备注:常用的有两个mock类:Mock和MagicMock,在多数示例中,Mock与MagicMock两个类......
  • 【视频】风险价值VaR原理与Python蒙特卡罗Monte Carlo模拟计算投资组合实例|附代码数
    原文链接:http://tecdat.cn/?p=22862 最近我们被客户要求撰写关于风险价值VaR的研究报告,包括一些图形和统计输出。风险价值(VaR)是一种统计数据,用于量化公司、投资组......
  • python学习——【第四弹】
    前言上一篇文章​​python学习——【第一弹】​​中,我们了解了python当中的流程控制语句,这篇文章我们接着学习python中的序列。这篇文章先给大家介绍不可变序列字符串和可......
  • 1行Python代码,对话ChatGPT,网友:太方便了!
    大家好,这里是程序员晚枫。最近ChatGPT火爆全球,哪怕你不是程序员,应该也听过他的大名了。今天我们就来一起体验一下~1行Python代码就够了!上代码导入poai这个库后,只需要1......
  • centos7安装python3.X(与Python2.X共存)
    先卸载自带的python3centos7自带python2.7和python3.6卸载自带的python3.6,重新安装python3.7卸载python3.6#卸载python3rpm-qa|greppython3|xargsrpm-ev--allma......
  • CSharp: donet 7 create logging File with EF Core 7.02
    ///<summary>///https://learn.microsoft.com/zh-cn/ef/core/logging-events-diagnostics/simple-logging///</summary>///<paramname=......
  • #yyds干货盘点#【愚公系列】2023年02月 微信小程序-电商项目-UI设计之蓝湖的使用
    前言蓝湖是一款产品文档和设计图的共享平台,帮助互联网团队更好地管理文档和设计图。蓝湖可以在线展示Axure,自动生成设计图标注,与团队共享设计图,展示页面之间的跳转关系。蓝......