1、数组与链表的区别?
数组:
1、内存连续存储:可以通过索引访问数组中的元素,查找速度快。
2、大小固定:数组的大小在创建时就被确定了,无法动态改变大小,如果需要扩容,通常需要重新分配一块更大的内存空间,将原有的数据拷贝过去
3、插入和删除效率低:由于数组的内存连续存储,插入和删除元素时需要移动后面的元素,效率较低。
4、随机访问快速:
由于数组的内存连续存储,可以通过下标进行随机访问,时间复杂度为O(1)
链表:
1、非连续非顺序存储结构:
链表是一种物理存储单元上非连续、非顺序的存储结构。
数据元素的逻辑顺序通过链表中指针链接次序实现
链表由一系列的节点组成,节点可以在运行时动态生成。
每个节点包含两部分内容:存储数据元素的数据区、存储下一个节点地址的指针域。
2、大小动态:
链表的大小可以动态增加或者减少,不需要预先分配一块固定大小的内存空间。
3、插入删除更高效
由于链表中的元素是通过指针相互连接的,插入和删除只需要改变指针指向,效率更高
4、顺序访问慢:
链表在进行顺序访问时,需要按顺序逐个遍历节点,时间复杂度为O(n)
2、函数中全局变量和局部变量
例1:函数中使用global,将改变原变量
def func(args):
global a
a+=10
args.append(100)
return args
lit=[1,2,3,4]
a=10
print(func(lit)) #[1,2,3,4,100]
print(lit) #[1,2,3,4,100]
print(a) #20
例2:函数中不使用global,函数外部不会改变原变量
全局变量可以供函数内部和函数外部使用,局部变量只能供函数内部使用
g_b = 3
def t1():
g_b = 2
print(id(g_b)) # 888
t1()
print(g_b) # 3
print(id(g_b)) # 666
def test(t):
t=1
print(t) # 1
a=2
test(a)
print(a) # 2
例3
g_b = 3
def t1():
global g_b
g_b = 2
print(id(g_b)) #666
t1()
print(g_b) #2
print(id(g_b)) #666
结论:
如果是不可变对象,在函数体的修改不会影响到实际参数的值,arg1的修改为100,不会影响到n1的值
如果是可变对象,在函数体内的修改回影响到实际参数的值,arg2的修改,append(10),回影响到n2的值
例4
def fun(arg1, arg2):
print('arg1的值:', arg1) #11
print('arg2的值:', arg2) #[22, 33, 44]
arg1 = 100
arg2.append(10)
print('arg1的值:', arg1) # 100
print('arg2的值:', arg2) # [22, 33, 44]
n1 = 11
n2 = [22, 33, 44]
print('n1的值:', n1) #11
print('n2的值:', n2) #[22, 33, 44]
fun(n1, n2)
-------------------------------------------------------------------------------------------------
print('n1的值:', n1) # n1的值: 11
print('n2的值:', n2) # n2的值: [22, 33, 44, 10]
例5
def fun(num):
odd = [] # 存奇数
even = [] # 存偶数
for i in num:
if i % 2:
odd.append(i)
else:
even.append(i)
return odd, even
num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = fun(num)
print(result)
([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
结论:
函数的返回值:
1、如果函数没有返回值(函数执行完毕之后,不需要给调用处提供数据),return可以不写。
2、函数的返回值,如果是1个,直接返回类型。
3、函数的返回值,如果是多个,返回的结果为元组。
3、函数传参爬坑:
例1
def d_list(l):
l.append(0)
print(l) # [0]、[0,0]
ll = []
d_list(ll)
d_list(ll)
print(ll) # [0,0]
list = [0, 1, 2, 3, 4]
list1=list
list.append(5)
print(list1) #[0, 1, 2, 3, 4,5]
print(list) #[0, 1, 2, 3, 4,5]
例2
def d_str(s):
s += '_python'
print(id(s))
s = 'msb'
d_str(s) #6666
d_str(s) #6666
print(id(s)) #8888
例3
a='abc'
b=a+'def'
print(id(a)) #666
print(id(b)) #888
例4
a='abc'
b=a+'def'
c=a+'def'
print(b,id(b)) #abcdef 1690101131056
print(c,id(c)) #abcdef 1690101130864
-------------------------------------------------------------------------------------------------
d='abc'+'def'
e='abc'+'def'
print(d,id(d)) #abcdef 1690101114096
print(e,id(e)) #abcdef 1690101114096
为什么b、c的内存地址不一样,d、e内存地址一样?
字符串的驻留机制原因:在编译前生效
例5
def clear_list(ll): #ll=[1, 2, 3]
ll = []
print(ll) #todo [] ll:局部变量
list1 = [1, 2, 3]
clear_list(list1)
print(list1) #todo [1, 2, 3] list1:全局变量
print('-----------------因为l是全局变量------------------')
def default_args_list(l=[1]):
l.append(1)
print(l)
default_args_list() #[1,1]
default_args_list() #[1,1,1]
例6
def d_list(l):
l.append(0)
return l
ll = []
l=d_list(ll)
print(l,id(l)) #[0] 2234991683776
l=d_list(ll)
print(l,id(l)) #[0,0] 2234991683776
print(ll,id(ll)) #[0,0] 2234991683776
def clear_list(ll): #ll=[1, 2, 3]
print('传入的参数ll的内存地址:',ll, id(ll)) # [1, 2, 3] 6666
ll = []
print('ll的内存地址:',ll,id(ll)) # [] 8888
list1 = [1, 2, 3]
clear_list(list1)
print('list1的内存地址:',list1,id(list1)) # [1, 2, 3] 666
-------------------------------------------------------------------------------------------------
ll = [1, 2, 3]
def clear_list(ll): #ll=[1, 2, 3]
print('传入的参数ll的内存地址:', ll, id(ll)) # [1, 2, 3] 6666
global list1
list1 = []
print('list1的内存地址1:',list1,id(list1)) # [] 8888
clear_list(ll)
print('list1的内存地址2:',list1,id(list1)) #[] 8888
-------------------------------------------------------------------------------------------------
def default_args_list(l=[1]):
l.append(1)
print(l)
default_args_list() #[1,1]
default_args_list() #[1,1,1]
4、字符串常用方法
a、split:如果括号中不加任何内容,按照空格进行拆分
rsplit()从右侧开始劈分
str3='hello world python'
str4=str3.split()
print(str4) #['hello', 'world', 'python']
---------------------------------------------------------------------------------------------
str4='hello,world,python'
str5=str4.split(',')
print(str5) #['hello', 'world', 'python']
print(str4.split(sep=',',maxsplit=1)) #['hello', 'world,python']
---------------------------------------------------------------------------------------------
'''rsplit()从右侧开始劈分'''
print(str4.rsplit())
print(str4.rsplit(','))
print(str4.rsplit(sep=',',maxsplit=1)) #['hello,world', 'python']
b、replace
str4='hello,world,python'
print(str4.replace('python','java')) #hello,world,java
str4='hello,world,python,python,python' #hello,world,java,java,python
print(str4.replace('python','java',2))
c、retrip
1、用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
2、该方法只能删除开头或者是结尾的字符,不能删除中间部分的字符。
3、返回值为移除字符串头尾指定的字符生成的新的字符串
如果参数chars不为None有值,那就去掉在chars中出现的所有字符。
print('abcabd'.strip('bc')) #abcabd
print('abcatd'.strip('at')) #bcatd
str2='helloworld'
print(str2.strip('d')) #helloworl
print(str2.strip('world')) #he
5、if elif else和if if else的区别
if elif else语句:从上往下执行,如果某一条语句成立,后面的语句不会执行
if if else语句:从上往下执行,所有成立的语句都将会执行,else语句与最近的if为一堆cp
num=10
if num>20:
print(1)
elif num>5:
print(2)
elif num>10:
print(3)
else:
print(4)
输出2
num=8
if num>3:
print(1)
if num>5:
print(2)
if num>10:
print(3)
else:
print(4)
输出1
2
4