Day2 - Python基础2 列表、字符串、字典、集合、文件、字符编码

本节内容

  1. 列表、元组操作
  2. 数字操作
  3. 字符串操作
  4. 字典操作
  5. 集合操作
  6. 文件操作
  7. 字符编码与转码

参考https://pythonav.com/wiki/detail/1/80/

1. 列表、元组操作

列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储、修改等操作

定义列表:

names1 = ['Alex',"Tenglan",'Eric']
names2 = list(['Alex',"Tenglan",'Eric'])
  

判断是不是列表:

>>> type(names) is list
True

对列表的操作

通过下标访问列表中的元素,下标从0开始计数

>>> names[0]
'Alex'
>>> names[2]
'Eric'
>>> names[-1]
'Eric'
>>> names[-2] #还可以倒着取
'Tenglan' 

切片:取多个元素

>>> name
['yhy', 'cfp', 'lk']
>>> name[1:]
['cfp', 'lk']  ##从索引1的位置切片到最后面
>>> name[0:1]  ##从索引0到索引1的位置 
['yhy']
>>> name[0::1]  ##从索引0到最后 步进为1 
['yhy', 'cfp', 'lk']
>>>

>>> name2 = name [1:]
>>> id(name)
42726728
>>> id(name2) 
42715272
>>>
###切片后的列表是一个新的列表
View Code

追加

>>> name.append('zs')
>>> name
['yhy', 'cfp', 'lk', 'zs']

插入

##指定索引位置,进行插入
>>> name.insert(0,'yhy1')
>>> name
['yhy1', 'yhy', 'cfp', 'lk', 'zs']
>>>

修改

##索引进行重新赋值操作就是修改
>>> name[0] = 'yhy2'
>>> name
['yhy2', 'yhy', 'cfp', 'lk', 'zs']

删除

##指定索引删除
>>> del name[0]
>>> name
['yhy', 'cfp', 'lk', 'zs']

###指定元素删除
>>> name.remove('zs')
>>> name
['yhy', 'cfp', 'lk']

###pop 删除最后一个元素,并且返回删除的元素
>>> name.pop()
'lk'
>>> name
['yhy', 'cfp']
>>>
View Code

清空

>>> name
['yhy', 'cfp', 1, 2, 3]
>>> name.clear()
>>> name
[]
View Code

扩展

####extend 指定一个列表进行扩展
>>> name
['yhy', 'cfp']
>>> l1 = [1,2,3]
>>> name
['yhy', 'cfp']
>>> name.extend(l1)
>>> name
['yhy', 'cfp', 1, 2, 3]
>>>
View Code

拷贝

####进行赋值操作就可以
>>> name
['yhy', 'cfp', 1, 2, 3]
>>> name1 = name
>>> name1
['yhy', 'cfp', 1, 2, 3]

####调用列表的方法进行复制
>>> name2= name.copy()
>>> name2
['yhy', 'cfp', 1, 2, 3]
>>>
View Code

copy真的这么简单么?那我还讲个屁!!。。。

统计

###统计name里面元素1的个数是多少
>>> name
['yhy', 'cfp', 1, 2, 3]
>>> name.count(1)
1
View Code

排序&翻转

>>> num = [1,22,44,55,2]
>>> num.sort()
>>> num
[1, 2, 22, 44, 55]
>>> num.reverse()
>>> num
[55, 44, 22, 2, 1]
>>>
View Code

获取下标

###index获取指定元素的下标
>>> num
[55, 44, 22, 2, 1]
>>> num.index(2)
3

元组

元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表

语法

names = ("alex","jack","eric")

它只有2个方法,一个是count,一个是index,完毕。

2.数字

int 有长整形和短整形
	python3中统一为int
	python2中有区分

基本的加减乘除这边就不写出来了
### 将 a 转为整形,而a的base=16 代表了,a是16进制
>>> a = 'b'
>>> int(a,base=16)
11
>>>
	

>>> r = 4
>>> bin(4)   ###将4变成2进行
'0b100'
>>> r.bit_length() ##当前数字的二进制,至少用n位表示
3
>>> 

3. 字符串操作

 创建字符串:

1 >>> name1 = 'crik'   ###创建字符串单引号和双引号没区别  
2 >>> type(name1)    注意:三个单引号和三个双引号 也可以表示字符串,且可以是多行
3 <class 'str'>      
4 >>> name2 = 'yhy'
5 >>> type(name2)
6 <class 'str'>

对字符串的操作:

重复输出:
>>> print('h'*3)
hhh

通过索引获取字符串字符,和切片一样
>>> name1
'crik'
>>> name1[1]
'r'

关键字 in
>>> name1
'crik'
>>> 'c' in name1
True
>>>

格式化输出
>>> name1
'crik'
>>> print("%s is good teacher."%name1)
crik is good teacher.
注意:%s是字符串 %d 是数字  %f是浮点数



字符串拼接:
>>> name1
'crik'
>>> msg = "is teacher"
>>> name1 + msg
'crikis teacher'

这样的方式效率非常的低。
最好的方式采用join的方法  重要!!!join是把一个可迭代对象变成了字符串
>>> ''.join([name1,msg])
'crikis teacher'
str = "src.plugins.ss"
a = str.rsplit(".",maxsplit=1)  ##从右边切割,且就切割一次
print(a)
###['src.plugins', 'ss']

字符串的内置方法:特别的多 差不多20个吧:

4. 字典操作

字典一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划、字母来查对应页的详细内容。

创建的方式:{ },用逗号分隔一组键值对

键必须是唯一的,所以他一定是不可变类型:

  • 不可变类型:整数(int)、浮点数(float)、布尔值(bool)、元组(tuple)、字符串(str)等
  • 可变类型:列表(list)、集合(set)、字典(dict)

值可以是任意的类型:

可变数据类型和不可变数据类型之间的主要区别在于它们在内存中的存储方式和对内存的使用。

对于不可变数据类型,一旦创建好了它们的值,就不能在原地修改,因此 Python 在内存中为它们分配的空间是固定的,并且可以被多个变量共享。

而对于可变数据类型,Python 在内存中为它们分配的空间是动态的,可以根据需要自由增加或减少,并且每个变量都拥有自己的空间。

语法:

info = {
    'stu1101': "TengLan Wu",
    'stu1102': "LongZe Luola",
    'stu1103': "XiaoZe Maliya",
}

字典的特性:

  • dict是无序的
  • key必须是唯一的,so 天生去重

增加:

View Code

删除:

View Code

修改:

View Code

查:

View Code

创建初始化字典:

#通过一个列表生成默认dict,有个没办法解释的坑,少用吧这
>>> info = dict.fromkeys(['s1','s2','s3'],'test')
>>> info
{'s3': 'test', 's2': 'test', 's1': 'test'}
>>>

多级字典嵌套及操作

View Code

字典的sorted方法:返回一个有序字典所有key的列表:

 

1 >>> info
2 {'s3': 'test', 's2': 'test', 's1'
3 >>> info.keys()
4 dict_keys(['s3', 's2', 's1'])
5 >>> sorted(info.keys())
6 ['s1', 's2', 's3']

字典的遍历:很重要!!!!

d={'name':'alex','age':40,'hobby':'girl'}
for i in d:
    print(i)

d={'name':'alex','age':40,'hobby':'girl'}
for i in d:
    print(i,d[i])     默认推荐第一种方式:效率高
for i,v in d.items(): 第二种有一个转换的过程 print(i,v)

5.集合操作

回顾:

创建列表的时候有两种,元组也是两种,而集合只有一种就是set方法
列表:1:[]   2:list(序列)    序列:就是有索引的;如:字符串,列表,元组
元组:1:()   2:tumple(序列) 

集合: set(可哈希对象) 可哈希对象可以理解成  如:列表,字符串 ,元组
注意1:虽然是由可哈希对象组成的集合,但是集合本身是不可哈希的
注意2:字典的键对象可以是( 整型 ,字符串 ,元组) 不可改变的对象:

集合是一个无序的,不重复的数据组合,它的主要作用如下:

1:去重,把一个列表变成集合,就自动去重了
2:关系测试,测试两组数据之前的交集、差集、并集等关系

常用关系操作:

 1 并集:
 2 s1=set([1,2,3,4])
 3 s2=set((4,5,6,7))
 4 print(s1.union(s2))
 5 print(s1 | s2)
 6 
 7 交集:
 8 s1=set([1,2,3,4])
 9 s2=set((4,5,6,7))
10 print(s1.intersection(s2))
11 print(s1 & s2 )
12 
13 差集:  只在s1中的元数
14 s1=set([1,2,3,4])
15 s2=set((4,5,6,7))
16 print(s1.difference(s2))
17 print(s1 - s2 )  
18          
19 对称差集:(项在t或s中,但不会同时出现在二者中) 
20 s1=set([1,2,3,4])
21 s2=set((4,5,6,7))
22 print(s1.symmetric_difference(s2))  #{1, 2, 3, 5, 6, 7}
23 print(s1 ^ s2 )   #{1, 2, 3, 5, 6, 7}
24 
25 超级;子集  
26 s1=set([1,2,3,4])
27 s2=set((4,2,3))
28 print(s1.issuperset(s2))  #True   s1 > s2 判断s1是不是s2的超级
29 print(s1.issubset(s2) )  # True  s1 <  s2   判断s1是不是s2的子集

基本操作:

基本操作:  
  
t.add('x')            # 添加一项  
  
s.update([10,37,42])  # 在s中添加多项  
  
   
  
使用remove()可以删除一项:  
  
t.remove('H')  
  
  
len(s)  
set 的长度  
增删

不可变集合:跟列表与元组的关系差不多

1 s=set('charr')
2 s1=frozenset('charr')
3 print(s)
4 print(s1)
5 
6 {'c', 'h', 'a', 'r'}
8 frozenset({'c', 'h', 'a', 'r'})

6. 文件操作

对文件操作流程

  1. 打开文件,得到文件句柄并赋值给一个变量
  2. 通过句柄对文件进行操作
  3. 关闭文件 

打开文件的模式有:

r  只读不能写
w  删除再写不能读
a  追加不能读

r+ 从头开始w   光标写的字最后
w+ 先删除再写  光标在最后
a+ 追加写,光标在最后
还有rb 和 wb 的模式:
那么b代表什么?  rb指的就是以字节读取,wb以字节写入.

我们知道在传送文件的时候,默认在硬盘保存的是字节,而我们要是以unicode去传输,还需要
进行decode下才可以;等到传送文件成功的时候,对方又需要将unicode进行decode放到硬盘中去
这样的话。速度就单纯的比用字节传输慢的多多了,多个道decode 和 encode的工序。

所以默认进行网络传输的时候必须为字节码。存到硬盘的数据也必须是字节。
这就是字节存在的意义,除此之外,字节毛无意义。

知识点:将unicode转成字节的方式:1: 内置的bytes函数  2:字符串自身的encode方法

>>> name = '搜索'
>>> bytes(name)
>>> bytes(name,'utf8')     ###指定要解码的对象,和解码方式
b'\xe6\x90\x9c\xe7\xb4\xa2'
>>> name.encode('utf8')
b'\xe6\x90\x9c\xe7\xb4\xa2'
>>>

基本操作  

打开文件
操作文件
文件的迭代器 readlines

截断truncate,你加参数就是截断全部

1 注意:的是truncate要需要写的权限:
2 >>> f= open('111.txt','r+',encoding='utf-8')
3 >>> s = f.truncate(2)  ###整个文件就只保存头两个的字符
4 >>> f.read()
5 'ne'
6 >>>

其他的一些操作:

1 isatty()判断是否是终端
2 readable()判断是否可读

with语句:

就是专门对应那些会打开文件不会关闭文件的家伙。。。。。

 1 正常文件对象:
 2 f=open(‘log’,’r’)
 3 f.read()
 4 f.close()
 5 
 6 with open(‘log’,’r’) as f:    ### 这是与f=open(‘log’,’r’)相等的
 7     f.read()
 8 
 9 
10 也可以拿到多个的句柄:
11 with  open(‘log’,’r’)  as  f_read, open(‘log2’,’w’) as f_write:
12     pass   

7. 字符编码与转码

      在说到字符编码的时候,我们要知道计算机是老美发明的,而且机器只能识别二进制 0 跟 1;

那么如何将字符(aBC)转换成机器可以识别的字符,我们就需要一个字符编码【就是一个映射关系   比如说 我规定八位的bit 0000 0001就表示A 】

最早的字符编码当然也是老美发明的叫ASCII码:

http://c.biancheng.net/c/ascii/

ASCII :只能存英文和拉丁字符;一个字符占1个字节,8位。

ASCII码一个字节可以存256个字符,但是没有都存满,这时候中国也想使用计算机啊,但是ASCII码不可以存中文,这时候中国就利用了ASCII码的最后几个字符中的一个去映射到一个更加大的字符集:

  • gb2312:只能6700多个中文1980年
  • gbk1.0:存了2万多个中文1995年
  • gb18030:存了2万7千多个中文 2000年

但是呢,每个国家都要用计算机啊,但是ASCII码的映射方式也就那么剩下的几个,这时候问题就来了,那剩下的几个空字符给谁用?这时候老美的iso组织就出来了发明了一种万国码:Unicode

 

Unicode是一个标准(并不是一种编码):

为什么叫万国码,就是将全世界的要使用的文字字符,映射到我这张更大的码表映射中去。比较早的时候是出现了

  • ucs2,用16位来表示所有的情况。2**16=65535  【这个就可以用到我们的中文汉字了】
  • ucs4,用32位来表示所有的情况。2**32=4294967296 【但是后面出现了表情?这时候就不够了,那么就扩大下码表,目前全世界用了21位,还有很多没用】

Unicode是将各国的编码append的形式的,位置是不变的,such as 是可以兼容GBK的

 

utf-8编码

出现了Unicode是吧,很美好,大家再也不用担心字符乱码等等问题。但是新的问题来了,大家都用ucs4,我存了字符串A  需要占用4个字节。

老美说原本我存一篇文章可能只要1M 现在我要用 4M,我不愿意啊,太浪费我的硬盘了。

还有呀你看。你现在一个月有30M的流量,如果你要用ucs4,咋搞原本30M的流量我可以看。好多羞羞的文字-我现在就只能看那么30/4的东西了。

然后我们就运势而生出来了utf-8编码。

utf8是对unicode进行压缩,到底是如何压缩?

  • 第一步:找模板

      码位范围(十六进制)                转换模板
       0000 ~ 007F              0XXXXXXX
       0080 ~ 07FF              110XXXXX 10XXXXXX
       0800 ~ FFFF              1110XXXX 10XXXXXX 10XXXXXX
      10000 ~ 10FFFF            11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
      
      例如:
          "B"  对应的unicode码位为 0042,那么他应该选择的一个模板。
          "ǣ"  对应的unicode码位为 01E3,则应该选择第二个模板。
          "武" 对应的unicode码位为 6B66,则应该选择第三个模板。
          "沛" 对应的unicode码位为 6C9B,则应该选择第三个模板。
          "齐" 对应的unicode码位为 9F50,则应该选择第三个模板。

    注意:utf-8表示中文时,用的是3个字节。

  • 第二步:码位以二进制展示,再根据模板进行转换

    码位拆分: "武"的码位为6B66,则二进制为 0110101101100110
    根据模板转换:
        6    B    6    6
        0110 1011 0110 0110
        ----------------------------
        1110XXXX 10XXXXXX 10XXXXXX    使用第三个模板
        11100110 10XXXXXX 10XXXXXX    第一步:取二进制前四位0110填充到模板的第一个字节的xxxx位置
        11100110 10101101 10XXXXXX    第二步:挨着向后取6位101101填充到模板的第二个字节的xxxxxx位置
        11100110 10101101 10100110    第二步:再挨着向后取6位100110填充到模板的第三个字节的xxxxxx位置
    最终,"武"对应的utf-8编码为 11100110 10101101 10100110  

除了utf-8之外,其实还有一些其他的 utf-7/utf-16/utf-32 等编码,他们跟utf-8类似,但没有utf-8应用广泛。

 

utf-8:采用了新的字符存放方式。位置变了
虽然有这个标准,大家就可以都使用这个了;但是中国奇葩说你就必须使用gb18030【当然每个国家都有自己的要求比如说:日本就必须要求支持JPK什么的】

(就如微软的系统在中国默认支持的gbk而不是utf-8

注:可以在cmd 命令右键属性查看;可以采用 chcp 修改

 

2:在python的字符集  

需知:

1 1.在python2默认编码是ASCII, python3里默认是unicode
2 2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 
3 不过在文件里存的还是utf-8,因为utf8省空间
4 3.在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string                                                   

in python2
默认是 ASCII码

in python3
默认是Unicode 【所以基本就不用做任何的转码】
【但是你非要没事干,要把Unicode转成GBK的话】

在encode的同时,会把数据转成了bytes类型
bytes是单独的数据类型:可以理解成[0-255]之间的纯数字类型
b=byte =字节类型

 

实验环境:

  • Windows的 cmd GKB格式:
  • 文件:111.txt
  • 编译器 python3
 1 111.txt文件:
 2 
 3 s = "你是我的神奇"
 4 print(s)
 5 s_to_gbk = s.encode('gbk')
 6 print(s_to_gbk)
 7 s_to_unicode = s_to_gbk.decode('gbk')
 8 print(s_to_unicode)
 9 
10 D:\>python3 111.txt
11 你是我的神奇
12 b'\xc4\xe3\xca\xc7\xce\xd2\xb5\xc4\xc9\xf1\xc6\xe6'
13 你是我的神奇

实验环境:

  • Windows的 cmd GKB格式:
  • 文件:字符编码python2.py
  • 编译器 python2
1 文件:
2 
3 s=’特斯拉’
4 
5 print(s)

执行:

 

错误:说 在这个文件中没有ASCII码的字符串且也没有定义采用的编码

修改:

文件:

 

执行:

 

解析:可以看到可以正确执行,但是是乱码,这是因为什么呢?

文件只是定义了文件的格式是utf-8,但是呢 cmd还是采用gbk的格式所以我们要修改cmd的编码 为utf-8 

 

posted @ 2018-03-16 09:32  你是我的神奇  阅读(286)  评论(0编辑  收藏  举报