Python 没有常量,不能保证他是常量,通常用全大写表示他是常量,很动态。和静态语言不同的主要是不用提前声明类型名,常用的数字(整数,浮点数直接赋值就是了),字符串就用双引号单引号
Python有很好的r'''
'''
语句可以保留里面内容的转义字符
当然转义字符也可以用\表示
pyhon表示逻辑的是and or not这些与c的符号表示不同,说明了Python更贴合人类自然语言(有实际意思),另外有一个c没有的数据类型,None
关于变量:变量可以分为两个部分(感觉对于所有的编程语言都通用),比如a='abd'第一步创建一个'abd',然后让变量名(在c 里面是地址,python是引用?)指向这个数据
下面,比如常用的交换语句:a=temp
a=b
b=temp
可以作为很好的例子,a指向temp的数据,然后a指向b的内容,接着b指向temp的内容
Python 另一个好处是数据没有上限!比如你不用担心你的int超范围,然后用高精度代码保证不超范围!
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件;
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。网页的源码上会有类似的信息,表示该网页正是用的UTF-8编码。
对于单个字符的编码,Python提供了ord()
函数获取字符的整数表示,chr()
函数把编码转换为对应的字符:
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'
由于Python的字符串类型是str
,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str
变为以字节为单位的bytes
。
Python对bytes
类型的数据用带b
前缀的单引号或双引号表示:
x = b'ABC'
要注意区分'ABC'
和b'ABC'
,前者是str
,后者虽然内容显示得和前者一样,但bytes
的每个字符都只占用一个字节。
以Unicode表示的str
通过encode()
方法可以编码为指定的bytes
,例如
>>> 'ABC'.encode('ascii') b'ABC' >>> '中文'.encode('utf-8') b'\xe4\xb8\xad\xe6\x96\x87' >>> '中文'.encode('ascii') Traceback (most recent call last): File "
", line 1, in UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
在bytes
中,无法显示为ASCII字符的字节,用\x##
显示。
反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes
。要把bytes
变为str
,就需要用decode()
方法:
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
如果bytes
中只有一小部分无效的字节,可以传入errors='ignore'
忽略错误的字节:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
len()
函数计算的是str
的字符数,如果换成bytes
,len()
函数就计算字节数:
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6
#!/usr/bin/env python3 #告诉mac和Linux这是python,Windows会自己忽略
# -*- coding: utf-8 -*- #告诉python采用UTF-8解释器
这个的作用是防止python源码过程出现乱码
4.格式化
1.基本格式化
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
%
运算符就是用来格式化字符串的。在字符串内部,%s
表示用字符串替换,%d
表示用整数替换,%f表示浮点数。%x表示十六进制有几个%?
占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?
,括号可以省略。
可以在哪些地方使用?比如单片机可以直接这样output在显示屏上?c的话编码LCD1602可以编码成这种简单的格式吗?更通编码习惯?
2.数字格式化
print('%2d-%02d' % (3, 1)) #输出的结果大概率是03和01
print('%.2f' % 3.1415926) #保留两位小数
可以用在单片机中的显示
3.转义输出
>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'
4.fstring
>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62
类似js的大括号语法,可以绑定数据。可以在写脚本的时候绑定变量的名称,然后直接改变变量名称获得输出。
>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62
list是一个可变的有序数组,相比于c的数组,列表可以更为自由(不用提前知道数组有多少个),相比于c中new出来的堆区,也不用担心没有delete,相对于vector则不用写长串的向量中的相量的形式。
所以毫无疑问还是从0开始,最后一个也是len(list)-1。不同的是,python的数组还可以从后面往前索引list[-1]。
另外,可以用append在列表尾部添加字符:
>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']
用inset在指定的索引位置插入字符
>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
也可以用pop删除字符
list.pop() #括号中没有索引说明直接删除最后一个,有索引则删除索引位置的
关于替换:直接对应索引赋值。对于python和c来说,都可以用索引直接赋值,如array[1]=1,array[1]=2.但是不同的点在于整体赋值的方面:c是不允许array=1出现的(因为数组名是一个地址),对于py说,这是语法对的,但是会出现问题,例子如下:
# 定义一个列表
list_example = [1, 2, 3]
print(f"重新赋值前,list_example 的类型: {type(list_example)},值: {list_example}")
# 重新赋值为整数
list_example = 1
print(f"重新赋值后,list_example 的类型: {type(list_example)},值: {list_example}")
list_example = [1, 2, 3]
# 重新赋值为整数
list_example = 1
# 尝试访问列表元素,会报错
try:
print(list_example[0])
except TypeError as e:
print(f"访问元素时出错: {e}")
可以发现,动态语言py直接改变了list数据类型!
另外,list和c不同的点还有:list中的数据类型可以不唯一,所以它不是一个纯粹的数组,而更像是一个集合
>>> p = ['asp', 'php']
>>> s = ['python', 'java', p, 'scheme']
要拿到'php'
可以写p[1]
或者s[2][1]
,因此s
可以看成是一个二维数组,类似的还有三维、四维……数组,不过很少用到。
tuple:元组,和list基本类似,但是不可以改变,相较之下就更加安全。类似于c中加了const
注意,tuple 用()表示,list用【】表示
tuple的陷阱:当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,比如:
>>> t = (1, 2)
>>> t
(1, 2)
如果要定义一个空的tuple,可以写成()
>>> t = ()
>>> t
()
tuple括号带来的歧义:
>>> t = (1)
>>> t
1
这种情况定义的是一个数,python会讲他理解为一个数,如果要是有元组,就变为
>>> t = (1,)
>>> t
(1,)
tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!有点像python给了一个地方装list,list里面的东西可以改变(那么如果改变list的数量可以吗?相对应改变数的话是可以,改变量可以吗?)
if elif else 和c大差不差,没有大括号语法,靠缩进确定区域,对于c中的switch case,py对应的是match case
score = 'B'
match score:
case 'A':
print('score is A.')
case 'B':
print('score is B.')
case 'C':
print('score is C.')
case _: # _表示匹配到其他任何情况
print('score is ???.')
对于input,input返回来的事str,记住这一点,和c不同的是,比如你输入123,其实返回的是字符串(c就是返回你实现定义的int变量)
# 复杂匹配的match实现(case中加条件语句,或者匹配多个项目[](匹配列表))
age = 15
match age:
case x if x < 10:
print(f'< 10 years old: {x}')
case 10:
print('10 years old.')
case 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18:
print('11~18 years old.')
case 19:
print('19 years old.')
case _:
print('not sure.')
主要还是for和while循环,当然也有continue,break
for x in range(5):#相当于c中的for (int i=0;i<5;i++){}
是的,这是python的一个新颖用法(当然c里面的map模块也有类似功能,但我不会)。
字典,顾名思义,就是很快找东西的。现实生活中是找字,计算机中是找数据。怎么找呢,我们自然想到用相应的名字配上相应的数据(就像我们对变量做的那样,但是我们刚好把它形成了本字典中)
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
这就是字典的用法,如果我们用其他方法来实现同样的效果,可能就需要两个列表,还要分别按照顺序一一对应起成绩和名字.而且随着列表增长,我们按照索引找列表的时间也增长.
# 使用index()方法查找元素对应的索引
my_list = [10, 20, 30, 40]
try:
index = my_list.index(30)
print(f"元素30对应的索引是: {index}")
except ValueError:
print("元素不存在于列表中")
# 使用循环遍历查找满足条件的元素及其索引
my_list = [10, 20, 30, 40]
target = 20
for index, value in enumerate(my_list):
if value == target:
print(f"元素 {target} 对应的索引是: {index}")
dic中通过key-value的方式来完成,value可以初始化的时候就加上,但是key要开始就有.单一对照,后面对value改的话会被覆盖(即value的值是最后一个加进去得知)
看看dic中key存不存在。如果你要加电话号码,你可能会先查一下之前是不是加过对方了,这个时候你可以通过语句
>>> 'Thomas' in d
False
先判断,或者直接用get ()
>>> d.get('Thomas', 11111111)
11111
如果你电话本有Thomas的电话,这个时候就会显示原本的电话(如22222),如果之前没有存有,就是1111
用pop()删除key-value
和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而变慢;(字典再厚,找单词找字的时间都是那几个步骤)
需要占用大量的内存,内存浪费多。(毕竟一本字典放在那里,肯定占空间)
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
字典是典型的空间换取时间的方法
set和dic区别不大,最大的不同是set只有key,而不用value配对(现实的字典来说,我们不会看见两个一样的字,因而set也不会用类似的key)。set可以用add添加,remove删除。set可以放入列表(类似一下子放入n个key)。
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
>>> s1 = {1, 2, 3}
>>> s2 = {2, 3, 4}
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错。
对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如:
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']
而对于不可变对象,比如str,对str进行操作呢:
>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'
虽然字符串有个replace()
方法,也确实变出了'Abc'
,但变量a
最后仍是'abc'
,应该怎么理解呢?
我们先把代码改成下面这样:
>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'
要始终牢记的是,a
是变量,而'abc'
才是字符串对象!有些时候,我们经常说,对象a
的内容是'abc'
,但其实是指,a
本身是一个变量,它指向的对象的内容才是'abc'
:
┌───┐ ┌───────┐
│ a │────▶│ 'abc' │
└───┘ └───────┘
当我们调用a.replace('a', 'A')
时,实际上调用方法replace
是作用在字符串对象'abc'
上的,而这个方法虽然名字叫replace
,但却没有改变字符串'abc'
的内容。相反,replace
方法创建了一个新字符串'Abc'
并返回,如果我们用变量b
指向该新字符串,就容易理解了,变量a
仍指向原有的字符串'abc'
,但变量b
却指向新字符串'Abc'
了:
┌───┐ ┌───────┐
│ a │────▶│ 'abc' │
└───┘ └───────┘
┌───┐ ┌───────┐
│ b │────▶│ 'Abc' │
└───┘ └───────┘
所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
dic={23:1,(1,2):[1,2,3]}
lty=[1,2,3]
dic={lty:'i'}
print(dic[lty])
Traceback (most recent call last):
File "c:\Users\jn\Desktop\python\.vs\1.py", line 3, in
dic={lty:'i'}
^^^^^^^^^
TypeError: unhashable type: 'list'
简单的例子知道什么是可以作为key