python学习--关注容易被忽略的知识点---(一)python基础

22 篇文章 0 订阅

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。
本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。

全系列:
(一)python基础
(二)函数
(三)高级特性
(四)函数式编程
(五)面向对象编程

前言

python是一种高级程序设计语言。
python可以做什么?

  • 网络爬虫,如从各大网站爬取商品折扣信息,比较获取最优选择等;
  • web开发。常用的web开发框架有:Django、Flask、Tornado 等。知名网站豆瓣、知乎、YouTube就是python编写的;
  • 人工智能应用。Python有很多库很方便做人工智能,比如numpy, scipy做数值计算的,sklearn做机器学习的,pybrain做神经网络的,matplotlib将数据可视化的;
  • 数据分析。“大数据”分析中涉及到的分布式计算、数据可视化、数据库操作等,Python中都有成熟的模块可以选择完成其功能。
  • 自动化运维。由于目前几乎所有Linux发行版中都自带了Python解释器,使用Python脚本进行批量化的文件部署和运行调整都成了Linux服务器上很不错的选择。
  • 其他。图形处理、数据库编程、网络编程、黑客编程等。

python有哪些优缺点?
优点:

  • 简单易学。语法简单,代码量非常少。比如,完成同一个任务,C语言要写1000行代码,Java只需要写100行,而Python可能只要20行。
  • 开发效率高。python有强大的第三方库,基本上可以实现在计算机上的任何功能。
  • 可移植性。由于它的开源本质,Python已经被移植在许多平台上。
  • 可扩展性。如果你需要你的一段关键代码运行得更快或者希望某些算法不公开,你可以把你的部分程序用C或C++编写,然后在你的Python程序中使用它们。

缺点:

  • 运行速度慢。Python是解释型语言,代码在执行时会一行一行地翻译成CPU能理解的机器码。相比C慢10倍。
  • 代码不能加密。解释型语言发布时必须把源码发布出去。
  • 线程不能利用多核。参考https://www.cnblogs.com/meteor9/p/10967156.html

python基础

数据类型和变量

几个要点:

  • 除法。/的结果是浮点数,//结果是整数。

  • 变量。对变量赋值x = y是把变量x指向真正的对象,该对象是变量y所指向的。随后对变量y的赋值不影响变量x的指向。

  • 大小限制。Python的整数没有大小限制;Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647。

  • 变量存储

a = 'ABC'
  1. 在内存中创建了一个’ABC’的字符串;
  2. 在内存中创建了一个名为a的变量,并把它指向’ABC’。

字符串和编码

详细请参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017075323632896

字符编码

为了将各国语言统一到一套编码,Unicode应运而生。
ASCII编码和Unicode编码的区别:

  • ASCII编码是1个字节,而Unicode编码通常是2个字节
  • 如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001

但是问题是,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算,所以又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。
在这里插入图片描述

现在计算机系统通用的字符编码工作方式:
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。

在这里插入图片描述

python字符串

最新的Python 3版本中,字符串是以Unicode编码的。
python提供了ord()函数获取字符的整数表示,
chr()函数把编码转换为对应的字符

由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。
如:x = b'ABC'

>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。
反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

如果bytes中包含无法解码的字节,decode()方法会报错。

>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
  ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte

如果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

由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

格式化输出

python采用格式化输出和C语言是一致的:

>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'

常见占位符:

占位符替换内容
%d整数
%f浮点数
%s字符串
%x十六进制整数

%s永远起作用,它会把任何数据类型转换为字符串:

>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'

另一种格式化字符串的方法是使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}、{1}……

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

list和tuple

list

list是一种有序的集合,可以随时添加和删除其中的元素。
list的方法包括:

  • append()
>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']
  • insert()
>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
  • pop()
>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']
  • 删除指定位置的元素,用pop(i)方法,其中i是索引位置
>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']

list里面的元素的数据类型也可以不同,比如:

>>> L = ['Apple', 123, True]

tuple

tuple和list非常类似,但是tuple一旦初始化就不能修改。
不可变的好处是代码更安全。

1.歧义问题
定义一个元素的tuple,如果这么定义:

>>> t = (1)
>>> t
1

得到的是1这个数,这是因为括号()既可以表示tuple中的括号,也可以表示数学中的小括号。
因此,定义一个元素的tuple应该这么定义:

>>> t = (1,)
>>> t
(1,)

2.可变的tuple

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

这里的‘[‘A’,‘B’]’发生了改变,为什么呢?看以下过程:

在这里插入图片描述

当我们把list的元素’A’和’B’修改为’X’和’Y’后,tuple变为:

在这里插入图片描述

表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。
tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向’a’,就不能改成指向’b’,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!

dict和set

dict

dict初始化

1.直接定义

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

2.dict()

d2 = dict(x = 1, y = 2)
print(d2['x'])

3.dict(zip())

d3 = dict(zip('abc', [1,2,3])
print(d3['b'])
>>> 2

4.dict(list)

list = [('a', 1), ('b', 2), ('c', 3)]
d5 = dict(list)
print(d5['a'])
 
>>> 1

5.defaultdict()方法。经常适用场景:计算key对应的value出现的个数。

#!/usr/bin/python
 
from collections import defaultdict
 
s = [('yellow',1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d =defaultdict(list)
for k,v in s:
d[k].append(v)
print(d.items()

6.fromkeys(seq[, value]).以序列 seq 中元素做字典的键,value 为字典所有键对应的初值

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
seq = ('Google', 'Runoob', 'Taobao')
 
dict = dict.fromkeys(seq)
print "新字典为 : %s" %  str(dict)
 
dict = dict.fromkeys(seq, 10)
print "新字典为 : %s" %  str(dict)

dict方法

1.get().输入key返回value,如果key不存在,返回None,或者指定一个value值。

>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

2.pop().删除一个key,对应的value也会被删除

>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}

3.dict.setdefault(key, default=None)。如果键不存在于字典中,将会添加键并将值设为default

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
dict = {'runoob': '菜鸟教程', 'google': 'Google 搜索'}
 
print "Value : %s" %  dict.setdefault('runoob', None)
print "Value : %s" %  dict.setdefault('Taobao', '淘宝')
for k, v in dict.iteritems():
    print k, v
# Value : 菜鸟教程
# Value : 淘宝
# google Google 搜索
# Taobao 淘宝
# runoob 菜鸟教程

4.dict.copy().返回一个字典的浅复制,只深拷贝父级目录。
dict.deepcopy().深层拷贝,父级目录,子级目录全部拷贝(需导入copy模块)。
赋值和各个copy 的区别:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
dict1 =  {'user':'runoob','num':[1,2,3]}
 
dict2 = dict1          # 浅拷贝: 引用对象
dict3 = dict1.copy()   # 浅拷贝:深拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用
dict4 = copy.deepcopy(dict1) #深拷贝,父级目录,子级目录全部拷贝

 
# 修改 data 数据
dict1['user']='root'
dict1['num'].remove(1)
 
# 输出结果
print(dict1)
print(dict2)
print(dict3)
print(dict4)
'''
{'num': [2, 3], 'user': 'root'}
{'num': [2, 3], 'user': 'root'}
{'num': [2, 3], 'user': 'runoob'}
{'num': [1, 2, 3],'user': 'runoob'}  #深拷贝字典不改变
'''

总结:
①原字典与赋值
紧密相连;一方改变,对方随之改变!
②原字典与浅拷贝
父级各自独立,子级紧密相连;一方改变,对方父级不变,子级随之改变!
③原字典与深拷贝
深拷贝独立门户,从此与原字典无关!
参考链接:https://blog.csdn.net/LeonTom/article/details/82761319

其他注意

和list比较,dict有以下几个特点:

  • 查找和插入的速度极快,不会随着key的增加而变慢;

  • 需要占用大量的内存,内存浪费多。
    而list相反:

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

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

要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key

set

在set中,没有重复的key
1.创建set

>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}

2.add()和remove()

>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}

>>> s.remove(4)
>>> s
{1, 2, 3}

set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错。(不会)

不可变对象

>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'

a是变量,而’abc’才是字符串对象!有些时候,我们经常说,对象a的内容是’abc’,但其实是指,a本身是一个变量,它指向的对象的内容才是’abc’.
写成如下容易理解:

>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'

未完待续…

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lingpy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值