1,字典推导式:
dict1 = {k:v for k,v in zip(list('abc'),list('123'))}
print(dict1)
如果不用字典推导式就要写成这样:
list1 = ['a','b','c']
list2 = [1,2,3]
z = zip(list1,list2)
for k,v in z:
print({k:v})
你看多麻烦!
2,元组的index方法
"""
1指要查找的元素,2和6是指定的索引范围,右侧闭合,也就是说写的是6,实际取5,如指定范围内没有找到,报错
如不写,默认全范围查找
"""
t1 = (1,2,3,4,5,1)
print(t1.index(1,2,6))
3,关于数据储存地址的指向问题:
def dengji(name, a=[]):
a.append(name)
print(a)
dengji('刘德华') # ['刘德华']
dengji('刘德华') # ['刘德华', '刘德华']
dengji('周润发', a = [])
dengji('周润发', a = [])
这个的答案是:
['刘德华']
['刘德华', '刘德华']
['周润发']
['周润发']
反正我第一次是做错了哈哈
"""
因为默认的列表的地址一直都未改变,哪怕是对列表内新增或者删除也好,
就算多次调用函数,默认列表地址不变,所以输出列表值的时候,会随之增减
但是,我后面重新传入一个空列表进去,这时默认列表的地址被新列表的地址取代,所以不会出现
多次调用函数,列表中的值随之增减的情况
"""
4,命名空间问题
下面的是关于命名空间的知识点,locals是查看局部命名空间内的命名元素,
如变量,函数等,但不包括嵌套函数内的变量
globals是查看全局命名空间,不包括函数里面的变量,但包括函数名(函数地址)
a= 12
def func(name):
age = 10
def fun2():
f = name
return f
print(locals())
func('kkk')
print(globals())
结果:
{'age': 10, 'fun2': <function func.<locals>.fun2 at 0x0000000002805510>, 'name': 'kkk'}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000002001CC0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, 'dengji': <function dengji at 0x000000000203C268>, 'a': 12, 'func': <function func at 0x0000000002805400>}
5,作用域
作用域指的是变量在程序中的可应用范围
Local(函数内部)局部作用域。
Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)。
Global(模块全局)全局作用域。
Built-in(内建)内建作用域。(指的是 builtins.py 模块)
a = 1
def func1():
b = 2
print(a)
def func2():
c = 3
print(b)
func2()
func1()
1
2
6,可变与不可变数据类型:
b = 1
def func1():
# b+=1
b = 2
print(id(b))
print(id(b))
func1()
print(b)
l1 = [1,2,3]
def func2():
l1.append(4)
print(id(l1))
print(id(l1))
func2()
print(l1)
8791052706640 #字符串的id
8791052706672
1
30368392 #列表的id
30368392
[1, 2, 3, 4]
不可变数据类型:
我建了一个全局变量b,然后建了一个函数,里面也创建了一个变量b
通过id可以发现,两个变量b并不是同一个,在函数里的b又开辟了一个内存空间,被视为局部变量,
局部变量b只在局部的作用域里面有效果,在里面做的任何修改也对于全局变量b没有任何影响
可变数据类型:
我创建了一个列表,然后在函数内引用列表做增删改的操作,然后打印列表,
函数内的操作都作用到了我建的全局列表中,
由此可见,二者的区别
7,nonlocal
print('----------------')
g = 1
def test():
g = 2
def test1():
g = 3
test1()
print(g)
test()
print(g)
"""
你会发现想在嵌套函数里就这样直接改上一个函数内定义的变量是无法实现的,
但是像global一样,nonlocal可以实现这样的功能
"""
print('----------------')
g = 1
def test():
g = 2
def test1():
nonlocal g
g = 3
test1()
print(g)
test()
print(g)
"""
而且nonlocal不会对全局变量有任何影响
"""
来看看结果:
----------------
2
1
----------------
3
1
8,关于zip函数的一些用法
t1 = ((1,2),(3,4))
t2 = (('a','b'),('c','d'))
z = zip(t1,t2)
print(list(z))
for i in z:
print(i)
print('1')
def func(t):
return {t[0]:t[1]}
rest = map(func,zip(t1,t2))
print(list(rest))
print(list(map(lambda t:{t[0]:t[1]},zip(t1,t2))))
结果:
[((1, 2), ('a', 'b')), ((3, 4), ('c', 'd'))]
[{(1, 2): ('a', 'b')}, {(3, 4): ('c', 'd')}]
[{(1, 2): ('a', 'b')}, {(3, 4): ('c', 'd')}]
是不是发现循环没有打出i
是因为zip后为一个生成器对象,
里面的值被list取完了
9,序列解包小知识
l1 = [1,2,3,4,5,6,7,8,9]
lst1,*lst2 = l1
*lst3,lst4 = l1
print(lst1)
print(lst2)
print(lst3)
print(lst4)
print(*l1)
"""
以上是一些解包的小知识点
"""
结果:
1
[2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8]
9
1 2 3 4 5 6 7 8 9
10,列表排序:
列表的排序,当遇到这种多层嵌套的列表,可在sort内用lambda函数定义key值,
选择取嵌套列表中的哪一个索引元素作为判断条件
l2 = [[2,5],[1,6],[2,7],[23,8],[9,0]]
l2.sort(key=lambda n:n[1])
print(l2)
l2.reverse()
print(l2)
结果:
[[9, 0], [2, 5], [1, 6], [2, 7], [23, 8]]
[[23, 8], [2, 7], [1, 6], [2, 5], [9, 0]]
11,几种超级简单的字典操作
dict1 = {'name':'kkk','age':'121'}
dict2 = {'name':'lll','height':'111'}
dict1.update(dict2)
print(dict1)
"""
有则更新,无则新增键值对
"""
for items in dict1.items():
print(items)
for k,v in dict1.items():
print(k,v)
"""
第一个遍历是以元组的形式返回键值对内容
第二个遍历则是直接输出键值对内容
"""
dict1 = dict()
print(dict1)
dict1 = dict(name='kkk',age = '123')
print(dict1)
dict1 = dict({'name':'kkk','age':'123'})
print(dict1)
dict1 = dict([('name','kkk'),('age',123)])
print(dict1)
dict1 = dict((('name','kkk'),('age',123)))
print(dict1)
dict1 = dict((['name','kkk'],['age',123]))
print(dict1)
dict1 = dict([['name','kkk']])
print(dict1,1)
"""
几种创建字典的方式,需要注意
"""
结果:
{'name': 'lll', 'age': '121', 'height': '111'}
('name', 'lll')
('age', '121')
('height', '111')
name lll
age 121
height 111
{}
{'name': 'kkk', 'age': '123'}
{'name': 'kkk', 'age': '123'}
{'name': 'kkk', 'age': 123}
{'name': 'kkk', 'age': 123}
{'name': 'kkk', 'age': 123}
{'name': 'kkk'} 1
12,几个简单的字符串方法
print(str1.ljust(15,'*'))
print(str1.rjust(15,'*'))
"""
这里是字符串左对齐右对齐的意思,不够的用*号补充
"""
print(str1.zfill(15))
"""
将字符串填充到一定长度,不够的地方用0,从左开始补充
"""
print(str1.center(15,'*'))
"""
字符串居中的办法,不够则用自定义符号进行填充
"""
13,二进制,八进制,十六进制
print(0xa)#十六进制的10
print(0xA)#十六进制的10,其字母不区分大小写
print(0o12)#八进制的10
print(0b1010)#二进制的10
print(bin(10))
print(oct(10))
print(hex(10))
结果是:
10
10
10
10
0b1010
0o12
0xa
14,简单的连续比较
print(1 == 2 < 3)
print(1 == 2 and 2 < 3)
print(5<7>6)
"""
这种比较运算其实就是连个运算之间用and连接的简化
否则1 == 2 为False,而False = 0 ,0< 3 成立,这时不符合我们的运算结果的
"""
print(2>True>0.1)
"""
顺便提一下,混合运算也是可行的
"""
15,python创建集合,要只要,set对字典也会创建集合
s1 = set('1')
print(s1)
s1 = {1,2,3,4,5,1}
print(s1)
l1 = [1,2,3,1]
print(set(l1))
str1 = 'hello'
print(set(str1))
dic1 = {'name':'kkk','age':123}
print(set(dic1))
print(set(dic1.values()))
"""
以上是一些集合的转换用法,
注:集合可以对字典进行强制转换,但得到的元素全为字典的key键!!!!
不过你可以加一个values
"""
结果是:
{'1'}
{1, 2, 3, 4, 5}
{1, 2, 3}
{'l', 'h', 'o', 'e'}
{'age', 'name'}
{123, 'kkk'}
16,面对对象的成员属性
class test():
def __init__(self):
self.num = 1
self.ls = [1,2,3]
t1 = test()
t2 = test()
t3 = test()
print(t1.num)
print(t2.num)
print(t3.num)
print('--------------')
t1.num = 2
print(t1.num)
print(t2.num)
print(t3.num)
print('--------------')
t1.ls[0] = 0
print(t1.ls)
print(t2.ls)
print(t3.ls)
print('--------------')
t1.ls = [4,5,6]
print(t1.ls)
print(t2.ls)
print(t3.ls)
print('--------------')
t1.ls.append('9')
print(t1.ls)
print(t2.ls)
print(t3.ls)
"""
在成员属性里面,每个对象所面对的属性都是其专有的,每建一个对象私有属性都会在内存中新存一份
怎么改都是改的对象自身的
"""
结果是:
1
1
1
--------------
2
1
1
--------------
[0, 2, 3]
[1, 2, 3]
[1, 2, 3]
--------------
[4, 5, 6]
[1, 2, 3]
[1, 2, 3]
--------------
[4, 5, 6, '9']
[1, 2, 3]
[1, 2, 3]
17,类的继承顺序以及属性
class A:
num = 1
def __init__(self):
self.num = 2
def test(self):
print('-----------> A ')
class B(A):
def __init__(self):
super().__init__()
self.n = 5
class C(A):
def test(self):
print('----------> C')
class D(B,C):
pass
d = D()
d.test()
print(D.__mro__)
"""
按类名.__mro__可以查看继承顺序
"""
a = A()
b = B()
print(A.__dict__)
print(a.__dict__)
print(B.__dict__)
print(b.__dict__)
# print(A.__dict__)
# print(a.__dict__)
print(B.num)
print(C.__dict__)
c = C()
print(c.__dict__)
"""
__dict__可以查看类与其实例对象的属性,例如在可以在重写__eq__方法的时候,
使用self.__dict__ == other.__dict__
对象.__dict__返回的是对象的成员属性,
类名.__dict__返回的是类属性以及其方法地址等
如果发生继承时,子类的__dict__中是没有父类的类属性的,
但是根据继承的特性,所调用的类属性在子类中找不到,就会去父类中寻找,依然可以调用的到
并且子类与父类的 成员属性 公用一个__dict__
强调一点,成员属性的__dict__与类的__dict__各存各的
注:
有些时候类的属性比较少的时候,当时又需要建许多对象,这时候就需要__slots__静态属性方法
来禁止每一个实例化的对象建立自己的__dict__,从而达到节省内存空间的效果
并且,并不是每一个对象都有__dict__的,例如系统的数字,列表,集合等对象
"""
结果:
----------> C
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
{'__module__': '__main__', 'num': 1, '__init__': <function A.__init__ at 0x0000000001F15400>, 'test': <function A.test at 0x0000000001F15510>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
{'num': 2}
{'__module__': '__main__', '__init__': <function B.__init__ at 0x0000000009E40D90>, '__doc__': None}
{'num': 2, 'n': 5}
1
{'__module__': '__main__', 'test': <function C.test at 0x0000000009E40E18>, '__doc__': None}
{'num': 2}
18,私有化属性
class Student():
__age = 10
def __init__(self):
pass
print(Student.__dict__)
Student.__name = 'kkk'
print(Student.__dict__)
"""
直接调用类想要新增一个私有化属性是愚蠢的,实际意义上,__name并不是私有化属性,因为在dict里面,他并不是_Student__name,
要知道python中私有化仅仅是重命名,他这个属性加进去在外部依旧能调用,没有啥意义
"""
结果:
{'__module__': '__main__', '_Student__age': 10, '__init__': <function Student.__init__ at 0x0000000002845510>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
{'__module__': '__main__', '_Student__age': 10, '__init__': <function Student.__init__ at 0x0000000002845510>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None, '__name': 'kkk'}
19,类属性的理解
class test():
ls = [1,2,3]
a = 1
def __init__(self):
pass
t = test()
e = test()
s = test()
print(t.ls)
print(e.ls)
print(s.ls)
print(test.ls)
print('---------------')
t.ls[0] = 0
print(t.ls)
print(e.ls)
print(s.ls)
print(test.ls)
print('---------------')
test.ls = [0,0,0]
print(t.ls)
print(e.ls)
print(s.ls)
print(test.ls)
print('---------------')
t.ls = [4,5,6]
print(t.ls)
print(e.ls)
print(s.ls)
print(test.ls)
print('===============')
print(t.a)
print(e.a)
print(s.a)
print(test.a)
print('===============')
t.a = 2
print(t.a)
print(e.a)
print(s.a)
print(test.a)
print('===============')
test.a = 3
print(t.a)
print(e.a)
print(s.a)
print(test.a)
"""
类属性的特性,内存中仅存一份,每个次调用都指向一个内存地址,
可变数据类型:
但是,对于可变数据类型,如果仅是修改,并不会影响这个特性
但是如果某一个对象进行了重建赋值创建,则其相当于新开辟了一个内存地址存储新的属性
不会再指向类属性,当然,其他对象不会受其影响,类也不会受其影响
但是,如果是类修改了这个值,所有对象所调用的类属性都会发生改变
不可变数据类型:
没有修改这一种说法,每次对象的调用都是一种新建属性
同样,如果是类调用属性进行改变,所有对象的调用都会同步,
已经调用而且没有循环重复的当然不会受影响
"""
结果是:
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
---------------
[0, 2, 3]
[0, 2, 3]
[0, 2, 3]
[0, 2, 3]
---------------
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
---------------
[4, 5, 6]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
===============
1
1
1
1
===============
2
1
1
1
===============
2
3
3
3
就先温故到这里了,后面有时间再继续和大家分享一下puthon基础语法知识