Python基础语法

一.数据类型和变量

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编码。

1.字符串

对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:

>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'

2.字符串转为比特

由于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的字符数,如果换成byteslen()函数就计算字节数:

>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6
 

3.转化编码保存

#!/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/tuple)

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++){}

六 字典!

1.dic

是的,这是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相反:

查找和插入的时间随着元素的增加而增加;

占用空间小,浪费内存很少。

 字典是典型的空间换取时间的方法

2.set

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,看看是否会报错。

3.不可变对象

对于可变对象,比如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

 

你可能感兴趣的:(Python学习,python)