Python学习笔记二:Python基础

文章目录

    • 1. 数据类型和变量
      • 1.1 数据类型
        • 1.1.1 整数
        • 1.1.2 浮点数
        • 1.1.3 字符串
        • 1.1.4 布尔值
        • 1.1.5 空值
      • 1.2 变量
      • 1.3 常量
    • 2. 字符串和编码
      • 2.1 字符编码
      • 2.2 Python的字符串
      • 2.3 格式化
        • 1. `%`
        • 2. `format()`
    • 3. 使用list和tuple
      • 3.1 list
      • 3.2 tuple
    • 4. 条件判断
      • 再议input
    • 5. 条件判断
      • 5.1 `for...in`
      • 5.2 `while`
      • 5.3 `break`
      • 5.4 `continue`
    • 6. 使用dict和set
      • 6.1 `dict`
      • 6.2 `set`
      • 6.4 再议不可变对象

  • Python语法采用缩进形式,有以下几点需要注意:
    1. 注释以#开头;
    2. 当语句以冒号:结尾时,缩进的语句视为代码块;
    3. 始终坚持4个空格的缩进;
    4. 大小写敏感;

1. 数据类型和变量


1.1 数据类型

1.1.1 整数

  • 在程序中的写法和数学中的写法一样,如1100-80800,等等;
  • 用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff000xa5b4c3d2,等等;

1.1.2 浮点数

  • 浮点数也就是小数,浮点数可以用数学写法,如1.233.14-9.01,等等;
  • 对于很大或很小的浮点数,需用科学计数法表示,如 1.23 1.23 1.23x 1 0 9 10^9 109就是1.23e9或者12.3e8,0.000012可以写成1.2e-5,等等;

1.1.3 字符串

  • 字符串是以单引号'或双引号"括起来的任意文本,比如'abc'"xyz"等等;
  • 如果'本身也是一个字符,那就可以用""括起来,比如"I'm OK"包含的字符是I'm,空格,OK这6个字符;
  • 用转义字符\来标识字符串内部包含的'";比如:
'I\'m \"OK\"!'

表示的内容就是:

I'm "OK"!
  • \n表示换行,\t表示制表符,\\表示的就是字符\
  • Python还允许用r''表示''内部的字符串默认不转义,如:
>>> print('\\\t\\')
\       \
>>> print(r'\\\t\\')
\\\t\\
  • Python允许用'''...'''的格式表示多行内容,此处注意...是提示符,不是代码的一部分;
>>> print('''line1
... line2
... line3''')
line1
line2
line3

1.1.4 布尔值

  • 一个布尔值只有TrueFalse两种值,在Python中,可以直接用TrueFalse表示布尔值(请注意大小写);
>>> True
True
>>> False
False
>>> 3 > 2
True
>>> 3 > 5
False
  • 布尔值可以用andornot运算;
  • 布尔值经常用在条件判断中,比如:
if age >= 18:
    print('adult')
else:
    print('teenager')

1.1.5 空值

  • None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值;

1.2 变量

  • 变量不仅可以是数字,还可以是任意数据类型;
  • 变量名必须是大小写英文数字_的组合,且不能用数字开头;
  • 等号=是赋值语句,可以把任意数据类型赋值给变量;同时不要将赋值语句的等号等同于数学中的等号;
  • 同一个变量可以反复赋值,而且可以是不同类型的变量,这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如Java是静态语言,赋值语句如下(// 表示注释):
int a = 123; // a是整数类型变量
a = "ABC"; // 错误:不能把字符串赋给整型变量

1.3 常量

  • 在Python中,通常用全部的大写的变量名表示常量;但Python根本没有任何机制保证PI不会被改变,所以全部大写的变量名只是一个习惯的用法;
  • Python中的除法:
  1. /除法计算结果是浮点数;除法计算结果是浮点数,即使是两个整数恰好整除,如:
>>> 10 / 3
3.3333333333333335
>>> 9 / 3
3.0
  1. //地板除,如:
>>> 10 // 3
3
  1. %取余,如:
>>> 10 % 3
1

2. 字符串和编码


2.1 字符编码

  • 8个比特(bit)作为一个字节(byte),一个字节能表示的最大整数就是255(二进制11111111=十进制255),最初只有127个字符被编码到计算机中,即ASCII编码;

  • 显然中文以及其他国家的语言,一个字节是不够的,故Unicode编码应用而生,最常用的是用两个字节表示一个字符(如果非常偏僻的字符,需要4个字节);

  • 虽然统一成Unicode编码,乱码问题消除了,但如果写的文本全都是英文的话,用Unicode编码比ASCII编码整整多了一倍存储空间,这就不划算了;

  • 于是出现了可变长编码UTF-8编码,UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的 英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节;

  • 总结一下计算机系统通用的字符编码工作方式:

  1. 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码;
  2. 用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件;
             
  3. 浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器;
             

2.2 Python的字符串

  • 在最新的 Python3.x 中,字符串是以Unicode编码的,支持多语言。比如:
>>> print('包含中文的str')
包含中文的str
  • 对于单个字符的编码,ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'
  • 如果知道字符的整数编码,还可以用十六进制这么写str
>>> '\u4e2d\u6587'
'中文'
  • Python的字符串类型为str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes
  • Python对bytes类型的数据用带b前缀的单引号或双引号表示:
x = b'ABC'
  • bytes每个字符都只占用一个字节
  • 以Unicode表示的str通过encode()方法可以编码为指定的bytes,例如:
>>> 'ABC'.encode('ascii')  # 纯英文的str可以用ASCII编码为bytes,内容是一样的;
b'ABC'
>>> '中文'.encode('utf-8') # 含有中文的str可以用UTF-8编码为bytes;
b'\xe4\xb8\xad\xe6\x96\x87'  # 在bytes中,无法显示为ASCII字符的字节,用\x##显示;
>>> '中文'.encode('ascii') # 含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错;
Traceback (most recent call last):
  File "", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
  • 反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
>>> b'\xe4\xb8\xad\xff'.decode('utf-8') # 如果bytes中包含无法解码的字节,decode()方法会报错;
Traceback (most recent call last):
  ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore') # 如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节;
'中'
  • 通过len()函数计算str包含多少个字符:
>>> len('ABC')
3
>>> len('中文')
2
  • len()函数计算的是str的字符数,如果换成byteslen()函数就计算字节数:
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8')) # 此处可见1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节;
6
  • 在操作字符串时,为了避免乱码问题,应始终坚持使用UTF-8编码对strbytes进行转换;
  • 当python的源代码中包含中文的时候,我们通常在文件开头写上这两行:
    1. 第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
    2. 第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
  • 声明了UTF-8编码并不意味着你的.py文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码:

2.3 格式化

1. %

  • 如何输出格式化的字符串,输出类似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'之类的字符串,而xxx的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式,在python中是和c语言中一样的方法,用%实现:
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
  • 常见的占位符有:
占位符 替换内容
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
  • 格式化整数和浮点数还可以指定是否补0和整数与小数的位数:
>>> print('%2d-%02d' % (3, 1))
 3-01
>>> print('%.2f' % 3.1415926)
3.14
  • 如果不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串:
>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'
  • 转义:%%表示一个%

2. format()

  • 用传入的参数依次替换字符串内的占位符{0}{1}……;

3. 使用list和tuple


3.1 list

  • python内置的一种数据类型是列表:list。他是一种有序的集合,可以随时添加和删除其中的元素,如:
>>> classmates = ['Michael', 'Bob', 'Tracy']
>>>classmates                   # 变量classmates就是一个list;
['Michael', 'Bob', 'Tracy']
>>> len(classmates)     # 可以用len()函数获得list元素的个数;
3
>>> classmates[0]     # 通过索引来访问每一个位置的元素,切记索引是在0开始的;
'Michael'
>>> classmates[2]
'Tracy'
>>> classmates[-1]    # 如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素;
>>> classmates[-2]
'Bob'
>>> classmates[-3]    # 以此类推,可以获得倒数第2个,倒数第3个;
'Michael'
  • list是一个可变的有序表,故可在list中追加元素到末尾:
>>> classmates.append('Adm')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adm']
  • 将元素插入到指定位置,比如索引号为1的位置:
>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
  • 删除末尾(指定位置)的元素,用pop()方法:
>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']
>>> classmates.pop(1)    # 用pop(i)方法删除索引位置是 i 的位置
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']
  • 把某个元素替换成别的元素,直接赋值即可:
>>> classmates[1] = 'Sarah'
>>> classmates
['Michael', 'Sarah', 'Tracy']
  • list里面的元素的数据类型也可以不同,如:
>>> L = ['Apple', 123, True]
  • list元素也可以是另一个list,如:
>>> s = ['python', 'java', ['asp', 'php'], 'scheme']
>>> len(s)
4
>>> s[2][1]
'php'
  • 空的list:
>>> L = []
>>> len(L)
0

3.2 tuple

  • 另一种有序列表叫做:tuple,但tuple一旦初始化就不能修改;
>>> classmates = ('Michael', 'Bob', 'Tracy')
  • 现在没有append(), insert()的方法,但其他方法和list都一样,不可变的tuple有可以使得代码更加安全,所以可能的情况下,尽量用tuple代替list;
  • 要定义一个只有1个元素的tuple时,要这样定义以免产生歧义:
>>> t = (1,)
>>> t
1
  • 最后看一个可变的tuple:
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
  • 此处tuple有三个元素:'a', 'b'和一个list

4. 条件判断


  • 计算机之所以能够做自动化的任务,是因为它可以做条件判断,例如:
age = 20
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')
  • 注意不要忘记课冒号:
  • 同时还可以用elif做更加细致的判断;
age = 3
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')
  • if语句执行有个特点,它是从上而下判断,如果在某个判断上是True,把该判断的语句执行以后,就自动忽略下面的elifelse
  • if判断语句还可以简写:
if x:
    print('True')
  • 只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False

再议input

  • 看一个有问题的条件判断,经常使用input()函数来读取用户的输入,例如:
birth = input('birth: ')
if birth < 200:
    print('00前')
else:
    print('00后')
  • 但当你输入1982时,程序后报错,这是因为input()返回的数据类型是str,而str是不能直接和整数相比较的,必须先把str转换为整数,这时我们就需要int()函数来完成这件事情:
s = input('birth: ')
birth = int(s)
if birth < 2000:
    print('00前')
else:
    print('00后')
  • 但是如果输入abc,又会得到一个报错信息,这是因为int()函数发现一个字符串并不是合法的数字时就会报错;
  • 那么此处如何检查并捕获程序运行期的错误呢?后面的错误和调试会讲到;

5. 条件判断


5.1 for...in

  • 两种循环,一种是for...in循环,依次把list和tuple中的每个元素迭代出来,例如:
names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)
  • 执行这段代码,会依次打印names中每一个元素的;
  • 所以for x in ...循环就是把每个元素代入变量x,然后执行缩进的语句;
# 计算1-100的整数之和
sum = 0
for x in range(101):
    sum = sum + x
print(sum)
  • 因为直接写1-100有点困难,所以有一个range()函数,可以生成一个整数序列,再通过list()函数可以转换为list,例如:
>>> list(range(5))
[0, 1, 2, 3, 4]

5.2 while

-另外一种是while循环,只要条件满足,就不断循环,条件不满足时退出循环;

# 计算100以内的所有奇数之和
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)
L = ['Bart', 'Lisa', 'Adam']
for x in L:
    print('Hello, %s!' % x)

Hello, Bart! 
Hello, Lisa! 
Hello, Adam! 

5.3 break

  • 在循环中,break语句可以提前退出循环;
# 打印出 1-10 
n = 1
while n <= 100:
    if n > 10: # 当n = 11时,条件满足,执行break语句
        break  # break语句会结束当前循环
    print(n)
    n = n + 1
print('END')

5.4 continue

  • 在循环中,可以通过continue语句来跳过当前的这次循环,直接开始下一次循环;
n = 0   # 此程序可以打印出1-10
while n < 10:
    n = n + 1
    print(n)
n = 0
while n < 10:
    n = n + 1
    if n % 2 ==0:   # 如果n是偶数,执行continue语句
        continue    # continue语句会直接继续下一轮循环,后面的print()语句不会执行
    print(n)

6. 使用dict和set


6.1 dict

  • python内置了字典dict,在其它语言中称为map,使用键-值(key-value)存储,具有极快的查找速度;
# 用普通方法来实现查找对应同学的成绩,需要两个list,当list越长,那耗时就越长
names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]
# 用dict方法来实现,只需“名字”-“成绩”的对照表,无论这个表多大,都不会变慢
>>> d = {'Michael' : 95, 'Bob' : 75, 'Tracy' : 85}
>>> d['Michael']
95
  • 至于为什么dict方式这么快,是跟他的存储方式有关的,在放进去的时候,必须根据key算出value的存放位置,这样,在取出的时候,才能根据key直接拿到value;
# 通过key的方式,将数据放入dict的方法
>>> d['Adam'] = 67
>>> d['Adam']
67
  • 由于一个key只能对应一个value,所以多次对一个key放入value,后面的值会把前面的值冲掉;
  • 如果key不存在,dict就会报错,为了避免key不存在的错误,有两种方法:
# 一种是通过in来判断key是否存在
>>> 'Thomas' in d
False
# 另外一种是通过dict()提供的get()方法,如果key不存在,可以返回 None
>>> d.get('Thomas')   # 此处注意返回None的时候python的交互式环境不显示结果
>>> d.get('Thomas', -1)
-1
  • 删除一个key,用pop(key)方法,对应的value也会从dict中删除;
>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}
  • 请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的;
  • dict是用空间来换取时间的一种方法,以后在python代码中几乎无处不在,所以请牢记的第一条就是dict的key必须是不可变对象,因为dict是通过key来计算value的位置的,这个算法叫做哈希算法(Hash),在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key,而list是可变的,就不能作为key;

6.2 set

  • setkey类似,也是一组key的组合,但不存储value;
  • 要创建一个set,需提供一个list作为输入集合
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
  • 传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1, 2, 3这三个元素,显示的顺序也不表示set是有序的;
  • 重复元素在set中自动被过滤;
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
  • 通过add(key)可以往set中添加元素,可以重复添加但不会有效果;
>>> s.add(4)
>>> s
{1, 2, 3, 4}
  • 通过remove(key)方法可以删除元素;
>>> s.remove(4)
>>> s
{1, 2, 3}
  • set可以看成数学意义上的无序和无重复元素的集合,因此两个set可以做数学意义上的交集,并集操作;
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
  • 同样set也不可放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”;

6.4 再议不可变对象

  • 看如下几段程序:
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']
>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'
  • 要始终牢记的是,a是变量,而'abc'才是字符串对象;
  • 当我们调用a.replace('a', 'A')时,实际上调用方法replace是作用在字符串对象'abc'上的,而这个方法虽然名字叫replace,但却没有改变字符串'abc'的内容。相反,replace方法创建了一个新字符串'Abc'并返回,如果我们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串'abc',但变量b却指向新字符串'Abc'了;
  • 所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的;

你可能感兴趣的:(Python入门笔记)