首页 > 编程语言 >Python学习之线性数据结构(二)

Python学习之线性数据结构(二)

时间:2023-02-18 19:31:30浏览次数:41  
标签:输出 字节 Python print bytes 元组 字符串 线性 数据结构

print(end=' ') end=表示语句结束后加入的东西

print(sep='') sep 表示间隔符 1 2 2 3 这个间隔的空格就是间隔符

print(1,2,sep=' ',end='') #打印数字1和2 间隔符为空格‘ ’ #以 结尾

分析一下菱形 *

 *
***
*

思路一 前置空格

行号 星号 前置空格 后置空格 1 1 3 6 2 3 2 4 3 5 1 2 4 7 0 0 5 5 1 2 6 3 2 4 7 1 3 6 n=7 char ='*' lead=' ' for i in range(-3,4): spaces=-i if i<0 else i # 等价于上面的if print(spaces * lead,end ='') print((7 - 2 * spaces) * char)

面试问你求素数的本质是,如果素数规模很大,你该如何考虑算法。

Python 内存管理

面试题: 1. 变量无须事先声明,也不需要指定类型,这是动态语言的特性 2. 变量只是一个标识符,指向一个对象,而这个对象被创建在内存"堆"中 3. Python编程中一般无须关心变量的存亡,一般也不用关心内存的管理 4. python使用引用计数记录所有对象的引用数。当对象引用数变为0,它就可以被 垃圾回收GC

#列表

X=[] 新建的空列表来说[],地址交给了x,引用计数为1

import sys sys.getrefcount(x) 函数调用自动加1,用完减一 。这函数是计算引用次数的 输出2

y=x sys.getrefcount(x) 此时输出3

sys.getrefcount([]) 这个应该输出几? 输出1 如何解释输出1 ? 这个写法表示新对象,肯定计数为1 实际[]引用计数0,调用完之后,适当的时候,gc清理它

a=1 #字符常量,数值或字符串等,他们是常量,常量处理不同,常量一旦创建不允许 修改,因此没有必要在内存中保留很多份

随机数模块:

元组tuple: 元组和列表有什么区别呢?列表是可增、可减,元组一旦创建则不能改变

列表 可变数据类型
元组 不可变数据类型

元组的初始化: t1= 1,2 这个属于封装 也属于元组 t2 =(1,2) 这个之间声明了是元组 (): 空元组 tuple(): 类加括号,表示空元组

t3=()
t4=tuple()
t3 == t4 会返回 True
解释器对不可变的tuple类型,做了优化

t4=(1,2,[3,4]) 元组也是容器

t5=(5) 这个不是创建元组,这个就是单纯的数值5,因为不知道这个()是想
增加优先级,还是创建元组。所有就同一按照是定义数值了来理解
t5=(5,):后面加一个逗号,才算定义元组

t5=tuple([1,3,5])
t6=tuple(range(5)) tuple()里面要写可迭代对象

元组的使用:

1.索引 
t6[0] 为 0 索引也是不允许越界
t6[10]=10 不允许修改元素,这样写是错误的

2.元组没有,增删改得方法。一旦元组创建好将不允许改变。

t7=([1]) *5 因为没加逗号所以不是元组,这个就相当于
t7 = [1] *5 这就是列表能修改
t7[1]=100 是可以的。
输出为[1,100,1,1,1]

t8 =([1],) *5 这个才是元组
输出为t8=([1],[1],[1],[1],[1])
t8[1]=200 可以这样修改吗? 不能修改,因为是元组
t8[1][0]=300 这个可以修改吗? 不是地址的能修改
这个是可以的,修改的是元组中列表的元素是OK的,因为元组存放列表的地址
元组所说的不能改变是,元素一旦定义好了是不能改变的,可以间接的通过地址可以修改的

t9=(1,2,[111,222])

元组的查询同列表一样的

1.学会利用索引技巧填充值
2.连续开辟一段很大的内存空间

newlist=[None] *len(nums) #必须要有,一般来说append效率也不错。 #但是,如果需要大空间列表,那么一次次append从 #原理来讲不如一次性开辟够 index=-1

while nums: m=max(nums) print(m) nums.remove(m) newlist[index]=m #利用索引填充值的技巧 index-=1

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

Python3起,字符串都是Unicode类型

初始化: r:取消所有转义字符 打印 \ 用\\ 写长语句的时候用三引号 ''' adsad asd '''

python 中没有提供其他语言都有的char类型,只有str类型
字符串一旦创建就是字面常量了,不能进行修改了

字符串拼接: 使用加法 + 就能对两个字符串进行连接 1.'a' +'b' 这个会输出什么? a+b并不是变成了ab,他的意思是我会生成一个全新 的字符串'ab',这个字符串依旧是字面常量.

2.用join 方法也可以,拼接两个字符串。
‘aaa’.join() ‘aaa’这个字符串调用这个join()方法

‘a’.join(‘bbb’),这个的意思是, 用‘aaa’这个字符串来拼接
join('bbb') join函数里可迭代对象的值。这里能迭代出‘bbb’三个
元素来.
这个会输出 'bababa' 输出一个join里的b,后面会拼接一个join前的a
这个生产的是一个全新的字符串

list('abc') 什么意思?
遍历'abc'中的这三个元素,并且放到列表中。会这样输出
['a','b','b']
tuple('abc') 元组也是这样的
('a','b','b')

join(),函数的拼接,是在元素之间的拼接。 这个相当于是在字符串之间加
分隔符。
join(),函数本身不能拼接非字符串类型,这是它的问题。
可以写为 ' '.join(map(str,range(5))) 用一下map函数

字符查找: x.index(‘1’): 找1 是不是在这个字符串中,找到则返回1 的下标index

y='1234'
y.index('123') 能找到并返回索引0 这个是找 子串

2.x='1\n2\n3\n'
x.conut('2') 输出1 找字符串中‘2’出现的次数

x.conut(r'\n') 这样一写,\n 就不代表转义字符了,这个\n就是两个字符了
这里会输出6

只要是这种动不动进行遍历的,数据规模大的时候一般都不用,效率比较低
count 能不用就不用,字符串的count个数问是题相当难的算法题
'abcabc' 单独知道个数不够,还要知道出现在哪里了,所以才难
index 少用

3.find 方法介绍 也是找字符串子串 推荐使用find方法找子串
s3='abcabc'
s3.find('c') 这里会输出 2
默认从左开始搜索,找到第一个'c',并返回他的索引

s3.rfinf('c') 这里输出5
默认从右开始搜索,找到第一个'c',并返回他的索引
find系方法,找不到,不会像index方法一样返回异常。find找不到就返回负数
我们一般用find的返回值 是不是大于等于0 >=0。大于等于0说明找到了

find 也可以指定子区间
s4='www.magedu.edu'
s4.find('edu',4,9) , s4.rfind('edu') 这个区间也是前包后不包
-1 11
先划定子区间,在子区间内找字符串
带r是从右开始找
4.时间复杂度:
find index count 方法都是O(n)
随着字符串数据规模的增加,而效率下降

字符串的分割 1. a='1,2,3,a,b,c' a.split() split 立即返回一个列表,找到分隔符切断 这样写会输出['1','2','3','a','b','c']

a.split('3')  以'3'分割,‘3’所在的位置进行分割,把‘3’删除
['1,2',',a,b,c']

b='\n\t\r\n a\nb\tc\t\n' #空格、换行符、tab,统称为空白字符space
b.split() #缺省值来分割,开头结尾切一刀,不会多出空串。
切割行为是:尽可能长的空白字符

b.split('\n') 以/n分割。指定了切割符,你说切什么就切什么

b.rsplit('\n') 从右向左开始切

最大切割数:
b.split('\n',2) 指定切割次数是两次

b.splitlines() 切成多行

d.partition(',') #立即返回三元组(part1,sep,part2) 相当于切一刀
d.rpartition(',') 从字符串右侧开始切

字符串替换函数 replace() d='a+b+c' d.replace('+','-',2) 2表示替换两次 输出为 'a-b-c' 把减号(-)替换为+ 。这个生成的是全新字符串。 python 中的字符串替换不是就地修改,而是生成一个全新的字符串 不支持模式匹配和替换,以后使用re

e='a***b***c***d***e***f***g'
e.replace('**', '*') ,此时e替换后会输出什么呢?
a**b**c**d**e**f**g 会减少一个*

字符串的移除 b='\n\t\r\n a\nb\t \nc\r\n' b.strip() 移除了什么? 会输出 'a\nb\t \nc' 这个字符串 括号里什么都不写把两端的空白字符都拿掉

b.strip('\n')  只移除了两端的指定的字符\n
\t\r\n a\nb\t \nc\r

b.strip('\t \nc\r') 两端拿掉字符集,跟字符的顺序无关

字符串首尾字符判断: a='1,2,3,a,b,c' a.startswitch('1') 这个字符串是用‘1’开头吗? a.endswitch('c') 这个字符串是用‘1’结尾吗? 这两个函数效率还是比较高的 a.startswitch('1',2) 从下标2开始查询 前包后不包

a.split(',').pop().upper() + 'd'
会输出'Cd' 一定要明白函数返回的类型

字符串的格式化: python这里print中输出换为了 % 1 "%d" %(i) C语言风格的输出 print("%d * %d = %d" %(3,4,12) ) %()百分号后面是一个元组,不能为 列表 2 print("My name is %(name)s, I am %(age)d" %{'age':20,'name':'mi'} ) %{}: 这里百分号后面是一个字典,根据小括号里的字符串,去字典中对应。 通过名字来找就跟顺序就无关了

3. age=20 name='Tom'
f'{age} {name}' 差值字符串输出
上面这些都是C风格的输出
%% : 两个%,会输出一个%

4. 进制的问题
%X :十六进制输出
%o : 八进制输出

5. fommat 函数推荐使用
位置或者关键字对应
print("{0} {1} {2} {a} {b}".format(1,2,3,a=100,b=200))
a和b想输出,是靠名称找值,必须按照顺序写,因为是元组,大括号里面的是元组的下标,表示输出谁.
a和b 按照名称对应,其余的按照顺序对应

print( "{}".format( (1,22) ) )这里会输出 (1,22) 这是一个元组

print("{0[1]}-----{0}".format{(1,22)})
这个0[1],会输出22 第0个元素,是元组,1,表示元组下标为0的值

print("{}+++++{}".format{ *(1,22) })
输出 '1++++22' 通过*号把这个变为了format(1,22)这是常用的

class A:
def __init__(self):
self.x=5
self.y=6

t=A()
print("{} {}".format(t.x,t.y)) 输出5 和6 不推荐

import datetime
d1 =datetime.datetime.now()

print("{}".format(d1)) 获取当前时间
2023-02-02 08:40:49.836858
如何单独获取年、月、日?

"{:%Y %y %M %m}".format(d1)
大写Y 输出2023 小写y输出23
%M: 分钟 %m:月份 %d:日 %H:小时 %S:秒

print("{:Y/%m/%d %H:%M:%S}".format(d1))
输出:2023/02/02 09:03:17

编码与解码: 1.字节序列: bytes叫做字节序列 bytearray 也叫做字节序列,但是可变

这两个主要用于,编码和解码当中。

"abc".endconde() str=>bytes 从字符串序列到字节序列
b'abc' b说明是bytes类型,这个类型不可变

bytes和bytearray这两个字节序列要转换为 str字符串
decode() 解码,把二进制码,变为字符串 默认解码 utf-8

python 3 中字符串使用的是unicode

在内存中,数据都是0和1,无差别的。当你指定某些字节,赋予数据类型的时候。这些数值就有了不同的理解。字符串类型,数值就要去找编码表了

Cpython,C语言中字符串尾部都有结束符,就是null字符,长度多1


中文 是双字节编码
gb2312 是大陆创建的编码表。gb指的是国家标准 国标。
gb2312问题在于收录的太少了。之后出现了gbk.
windows使用的内部就是gbk。 所谓gbk就是双字节系统,兼容
ASCII

unicode iso 国际组织。需要兼容ASCLL。
完成双字节把全世界已知字符装进去
unicode 的问题在于始终用两个字节,描述ASCII 这样一个字节的
也用了两个字节,浪费空间

gbk和这个unicode 编码有映射关系的

str 在字符的世界中,是有编码的,要查编码表
bytes 在字节的世界里,只有一个个字节,没有编码

互联网时代,传输数据,字节。为了解决单字符也传输两个字节的问题
为了适应网络传输,和为了能把全世界的文字收录在内,诞生了一种适合于网络
传输的编码方式 叫做 utf 。
utf-8 变字长的编码1-6个字节表示。他能兼容所有字符
ascii 单字节:中文字符绝大多数落在3个字节上
一些特殊符号需要4个字节
压缩,字符的压缩比非常大

字节序列:存在形式是二进制 bytes 不可变字节序列 bytearray 是可变字节数组

初始化:
b1=bytes() print(b1) 会输出 b'' 表示空字节,不可变类型,一但定义
不可修改
b2 = b''
b3 = bytes(5)
b3 = b'\x00\x00\x00\x00\x00'
b4 = bytes('abc','utf-8')
b4 = b'abc'
b4 = 'abc'.encode('gbk')
对于ascii 码来说utf8 和gbk 得到的二进制是一样的
b6 = bytes(range(10)) 参数可以是可迭代对象
b6 = bytes(range(0x30,0x3a))
print(bytes(range(65, 91)))
输出 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
bytes(range(65, 91,2)) 表示间隔为2

类方法构建:
b'abc'.startswitch(b'ab')
b'abc'这个是对象

bytes() 这个是用类来构建一个bytes对象
bytes.fromhex() 没有bytes 对象,用类型,方法,构建一个bytes对象
写字符串
bytes.fromhex('') 括号里写字符串,求16进制的表达
hex(9) hex函数要数字

bytearray() 可变的这个,数组,list
bytearray(range(65,70))
bytearray(b'ABCDE')

字节序: abc 它在内存中怎么放呢? 对于一个字符串来讲,我们很容易知道谁是头谁是尾。把尾部放在大地址上。 我们把尾部放在大地址上的方式称为大端模式。 尾部如果放在小地址上,称为小端模式。几乎所有的字符串都采用了大端模式 地址顺序 0 1 2 3 4 5 6 7。 大端模式容易追加字符串

字符串采用了大端模式Big endian,把尾部字符往高地址放

对于 int类型,C语言,有1字节整型,无所谓大小端
2字节开始,都存在大小端模式了
2个字节:0x61 62 63 整数类型,大小端问题。

如何理解字节序呢?
字节序就是一个多字节的数据类型,在内存中的分布方式。所谓多就是超过一个字节的数据在内存中的分布方式。一般采用大端模式。
二进制数字,最低位是尾部

int 和bytes相互转化

切片: 只要有序就可以切片,可以索引的就可以切片 线性结构: list列表 tuple元组 str字符串 bytes 字节序列 bytearry

x=list(range(10))
会输出 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
切片语法
x[start:stop] 索引范围 叫做切片
x[index] 索引
x[1:3] 输出 [1, 2] 前包含后不包含 输出下标1到下标3的元素
start 为0,可以不写出来。stop如果是末位也可以不写
"abc" [1:-2] 切片的结果是本类型,列表切不出来就是空列表

x[:] :从头到尾打印 x[::] x[::1]

x[::-1] :会逆序输出 [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
x[::2] :sep=2 步长为2 会输出 [0, 2, 4, 6, 8] 间隔为2输出一次

x[::-2] 负号代表从右侧开始输出 [9, 7, 5, 3, 1]
x[2:2] : 下标2开始走,步长为2

切片的本质: x=[1,2,3,4,5] y=x[:]

x==y 吗?  x is y 吗? 这个两个会输出什么?
id()函数会输出对象的地址
x==y 输出true 内容相同,但是地址不同

切片本质,从start到stop,做一个区间,中间间隔使用step.把取出的元素合并成了一个本类型的对象。切片之后返回的是一个全新对象,会开辟新的内存空间

数据规模大,不推荐用切片

切片赋值问题 a=list(range(5)) 输出 [0, 1, 2, 3, 4]

print(id([1, 2, 3, ]))
print(id([4, 5, 6, 7])) 为什么这两个列表会输出一样的地址值
该如何解释呢?
都输出了 1419619112256 这两个地址
1419619112256
因为第一行输出完以后,没有变量进行记录,所以被垃圾回收了。第二行也同理。第一行是临时的变量,运行完就回收了。因此第二行可以在这里进行使用这个内存空间
赋值既定义

a=[0,1,2,3,4]
t=list()
t[:]=a t会输出 [0,1,2,3,4] 问题是 t==a吗? t is a 吗?
t与a内容相等,地址不同

t[1:2] = 50 会出现语法错误,切片要赋值只能使用可迭代对象进行赋值
t[1:2] = (50,) 换成元组就可以赋值了

t=[0,10,11,12,13,14,15,16,17,18,19]
t[1:3]=[20] 这个的意思就是把下标 1到2 这个范围替换为20因为只有一个
数字20.所以这两个位置变为一个位置 最后输出
[0,20,12,13,14,15,16,17,18,19]
这个就是切片赋值

切片赋值好吗? 为什么?
确实方便,但是不够好。因为两个空,变为一个空的时候会发生挪动。一旦数据规模过大,时间复杂度会很高,程序运行效率会变差

1. 求100以内的素数,要考虑时间复杂度,面试出这题并不简单,本质是问你
1000000,以内的素数。不能大意,要特别小心
22分钟


杨辉三角问题:
第一行和第二行都是1,中间这一行等于上一层两项之和
第几行有几个数字
第一行和第二行是特例

i=2 cur=[1] pre=[2-1]=[[1,1]]

j=2-1=1 循环一次从0开始循环 j会=0 cur.append(pre[0]+pre[0+1])

46分钟

标签:输出,字节,Python,print,bytes,元组,字符串,线性,数据结构
From: https://blog.51cto.com/u_14743944/6065512

相关文章

  • 关于python中将字典的所有key组成一个列表的方式
    关于python的字典,我们可以通过MyDict.keys()得到这个字典的所有的key,然后还能通过for循环进行遍历但是细心一点、我们可以发现,MyDict.keys()其实是一个<class'dict_ke......
  • List集合-数据结构
    List集合-数据结构数据结构是计算机存储,组织数据的方式.是指相互之间存在一种或多种特定关系的数据元素的集合.通常情况下,精心选择的数据结构可以带来更高的运行或者......
  • 数据结构
    数组地址的计算1维数组,默认是行优先,也就是先横着放。2位数组行优先,相当于最外围数组横着放,列优先就是最里面的先横着放。稀疏矩阵图(没懂)顺序表和链表队列有......
  • Python 学习01 基础知识
    ......
  • 用python绘制1960年到2019年全国GDP增长图
    frompyecharts.chartsimportBar,Timelinefrompyecharts.optionsimport*#处理数据f=open("D:/1960-2019全球GDP数据.csv","r",encoding="GB2312")#读取每一行,返回是......
  • Windows下面查看python安装路径的快捷方法
    在Windows(Win10-Win11)下面,查看python的安装路径,比较快捷的方法是:打开CMD窗口,运行wherepython便可以查看python安装路径,不同机器不一样:C:\Users\WinUser01\AppData\Loca......
  • python获取子线程结果
    fromthreadingimportThreadclassMyThread(Thread):def__init__(self,func,args=()):Thread.__init__(self)self.func=funcs......
  • [数据结构] AVL树
    AVL树的基本概念AVL树的定义AVL树得名于它的发明者G.M.Adelson-Velsky和E.M.Landis。AVL树本质上是一颗二叉搜索树,并且本身带有平衡的条件,即每个结点的左右子树的高......
  • python Django基础
    django官网https://www.djangoproject.com/download/文档https://docs.djangoproject.com/安装Django安装官网LTS版本pipinstalldjango==3.2.15Django命令>django......
  • python面向对象
    1、面向对象和面向过程的区别1.1、面向过程:是一种以事件为中心的编程思想,更关注过程。简单的问题可以用面向过程的思路来解决,直接有效,但是当问题的规模变得更大时,用面向过程......