python学习-基础-day2-模块列表字符编码

一、PYC文件

python首次执行某个文件,会生成一个pyc的编译文件,下次执行的时候首先会找是否有pyc文件,再检查文件日期,这样会减少编译时间.

以下摘自head first Python一书:

解释器第一次执行代码时,它会读入代码,并转换为一种中间字节码格式,最终所要执行的就是这些字节码(这种思想与Java JVM的工作原理很类似:利用Java技术编译代码时,java代码会转换为一个类文件)。

Python解释器非常聪明,下一次模块时会跳过这个转换阶段,因为它能确定原来的模块代码何时有变化。如果你的模块代码没有变,就不会发生任何转换,相应的就会执行“编译”版本的代码。如果代码确实发生变化,

则会发生转换(创建一个新的.pyc文件)。这样做的好处是让程序运行的更快。

 

二、模块

模块就是一个包含python代码的文本文件。对模块的主要需求就是要求文件名以.py结尾。

比如我在一个名为modtest.py的文件里面定义了一个叫做func1的函数,我可以在同一个目录下再新建一个python文件,然后调用func1这个函数。如何调用如下

import modtest #导入这个模块,不需要加py后缀

modtest.func1()  #调用函数,前面一定要加modtest.,不然直接调用func1会找不到此函数

解释:主python程序中(以及IDLE,shell中)的代码与一个名为__main__(两边各两个下划线)的命名空间有关。将代码放在其单独的模块中时,

python会自动创建一个与模块同名的命名空间。所以上面模块中的代码与一个名叫modtest的命名空间有关,就如同姓氏一样,可能你的主python程序中

也有叫做func1的,或者其它模块中也有叫func1的,如果没有前面的命名空间,就不知道调用谁,或者找不到。

以上也可以 from modtest import func1

调用func1直接可以func1()使用,前提是当前的python文件中没有叫func1()的函数。#当时测试过,如果执行func1()在新定义func1()的前面调用,那么会使用你导入的,如果在新定义的func()后面调用,值就行新定义的func1(),可能新定义func1把导入的替换掉了

 

 

补充:PyPI,Python包索引(python package index),第三方模块的集中存储库

import 模块名

现在当前文件路径下找模块名,再在python的环境变量里面找

使用import sys

sys.path可以获得python的环境变量

 

安装第三方模块,默认会安装在$python3.5\Lib\site-packages目录里

在win上用pip命令安装报错:unable to create process using ''''

百度了下:python -m pip install 模块文件

关于模块,可以参考:http://www.cnblogs.com/wupeiqi/articles/4963027.html 

三、字符编码与转码(copy alex的)

 

详细文章:

http://www.cnblogs.com/yuanchenqi/articles/5956943.html

http://www.diveintopython3.net/strings.html

需知:

1.在python2默认编码是ASCII, python3里默认是unicode

2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 不过在文件里存的还是utf-8,因为utf8省空间

3.在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string

 

 上图仅适用于py2

 1 #-*-coding:utf-8-*-
 2 __author__ = 'Alex Li'
 3 
 4 import sys
 5 print(sys.getdefaultencoding())
 6 
 7 
 8 msg = "我爱北京天安门"
 9 msg_gb2312 = msg.decode("utf-8").encode("gb2312")
10 gb2312_to_gbk = msg_gb2312.decode("gbk").encode("gbk")
11 
12 print(msg)
13 print(msg_gb2312)
14 print(gb2312_to_gbk)
15 
16 in python2
#-*-coding:gb2312 -*-   #这个也可以去掉
__author__ = 'Alex Li'

import sys
print(sys.getdefaultencoding())


msg = "我爱北京天安门"
#msg_gb2312 = msg.decode("utf-8").encode("gb2312")
msg_gb2312 = msg.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔
gb2312_to_unicode = msg_gb2312.decode("gb2312")
gb2312_to_utf8 = msg_gb2312.decode("gb2312").encode("utf-8")

print(msg)
print(msg_gb2312)
print(gb2312_to_unicode)
print(gb2312_to_utf8)

in python3
python3

四,列表

1,列表中允许存在相同的元素

可以用.count("name")去查看你

如:

list1 = [1,2,3,4,1,2,5,]
print(list1)
print(list1.count(2))

输出:

2,copy

2.1列表1 = 列表(因为我犯过这个错误,列表中不要些这种)
names = ['cui','wang','luo','zhang','xu']
print(names)
names_1 = names
print(names_1)
names[1] = 'zhao'
print(names)
print(names_1)
print(id(names))
print(id(names_1))

输出为:

['cui', 'wang', 'luo', 'zhang', 'xu']
['cui', 'wang', 'luo', 'zhang', 'xu']
['cui', 'zhao', 'luo', 'zhang', 'xu']
['cui', 'zhao', 'luo', 'zhang', 'xu']

 11928968
 11928968

可以看到如果列表采用c = a, a= b,b = c,这种a,b互换值是不行的,列表1 =列表2 仅仅只是复制了对对象的引用,即 names 和 names_1 指向的是同一个对象,所以如果改变了该对象的元素的话,则两个表所指向的对象都会改变,因为实际上就是同一个对象。可以由id(names)和id(names_1)看出两者指向的对象在内存中的地址是相同的,即是同一个对象

补充一下:列表2 = 列表1*n,将列表1里面的元素翻n倍,列表2与列表1为相互独立的列表

>>> names = ['cui','hu','zhang','wang','luo']
>>> names_copy = names * 3
>>> names_copy
['cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo']
>>> print(id(names),id(names_copy))
56032904 55907784

 

2.2 浅copy
names = ['cui','wang','luo',['zou',29],'zhang','xu']
print(names)
names_copy = names.copy()
names[0] = 'CUI'    #更改names列表里的第一个值
names[3][0] = 'ZOU min'  #更改names列表里第三个列表里的第一个值
print(names)  
print(names_copy)
['cui', 'wang', 'luo', ['zou', 29], 'zhang', 'xu']
['CUI', 'wang', 'luo', ['ZOU min', 29], 'zhang', 'xu']
['cui', 'wang', 'luo', ['ZOU min', 29], 'zhang', 'xu']

浅copy是最常用的copy,只会copy列表第一层的对象,列表第一层改动的时候,不会影响copy的列表,但是第二层改动便会影响,因为这个例子中的子列表

令有3种实现方式:

import copy
names = ['cui','wang','luo',['zou',29],'zhang','xu']
print(names)
names_copy = copy.copy(names)

######################
names_copy = list(names)

##########################
names_copy = names[:]
2.3 深copy deepcopy(完全copy,基本不用,如果一个大表再完全copy一份,相当于占用两个内存空间)
1 import copy
2 names = ['cui','wang','luo',['zou',29],'zhang','xu']
3 print(names)
4 names_copy = copy.deepcopy(names)
5 names[0] = 'CUI'    #更改names列表里的第一个值
6 names[3][0] = 'ZOU min'  #更改names列表里第三个列表里的第一个值
7 print(names)
8 print(names_copy)
print(id(names),id(names_copy))

输出

['cui', 'wang', 'luo', ['zou', 29], 'zhang', 'xu']
['CUI', 'wang', 'luo', ['ZOU min', 29], 'zhang', 'xu']
['cui', 'wang', 'luo', ['zou', 29], 'zhang', 'xu']

14440968 14441480

看出,无论names如何改动,都不影响names_copy,反之亦然,因为两者指定的是完全不同的内存地址

3,切片

列表元素的下表是从左到右是从0,1,2。。。。。,从右到左是-1,-2,-3

切片的原则是包头不包尾如names[1:-1]指选择第2个元素(下标为1)到倒数第2个(倒数第一个前面那一个)

names
['cui', 'wang', 'luo', 'zhang', 'xu']
names[-2:-1]
['zhang']
names[0:2]
['cui', 'wang']
names[0:]
['cui', 'wang', 'luo', 'zhang', 'xu']
names[:-2]
['cui', 'wang', 'luo']
names[:]
['cui', 'wang', 'luo', 'zhang', 'xu']

下标0是可以省略的,names[:]表示全部,names[-3:]表示倒数3个

4,追加

names.append('NEW')
names
['cui', 'wang', 'luo', 'zhang', 'xu', 'NEW']

5,插入

names = ['cui','wang','luo','zhang','xu']
names.insert(1,'charu1')
names.insert(-1,'end')   #在最后元素的前面插入'end'
print(names)

最后面插入可以用上面的追加

6,修改

names[-2] = 'haha' 

将倒数第二个元素修改为'haha'

7,删除

del names[2] #删除第3个元素

del names[3:5] #删除列表中第4个到第5个元素

del names  #将列表nanmes整个删除,这样print(names)会报没有定义变量names

或者

names.pop()  ##删除最后一个元素

names.pop(2) ###删除第3个元素

或者(删除指定的元素,前提是知道列表中包含这些元素)

['cui', 'wang', 'luo', 'zhang', 'xu']
>>> names.remove('luo')
>>> names
['cui', 'wang', 'zhang', 'xu']
>>>

names = ['cui','wang','luo','zhang','xu',1,2,3,4]
for n in ('wang','zhang',1,4):
    names.remove(n)
else:
    print(names)
如何删除一个列表中多个元素

 

8,扩展

names = ['cui','wang','luo','zhang','xu']
age = [1,2,3,5]
names.extend(age)

输出:

['cui', 'wang', 'luo', 'zhang', 'xu', 1, 2, 3, 5]

扩展:extend与+,+=的区别(表面看效果一样,都是将后面列表元素全部追加进前面列表中)

>>> names
['cui', 'wang', 'zhang', 'xu']
>>> age
[1, 2, 3]
>>> names = names + age
>>> names
['cui', 'wang', 'zhang', 'xu', 1, 2, 3]
列表1+列表2

 

names = ['cui','wang','luo','zhang','xu']
age = [1,2,3]
print(id(names),id(age))
names.extend(age)
print(id(names))

输出:
12059912 12040968
12059912

使用extend,names在扩展前后还是指向同一个内存地址

names = ['cui','wang','luo','zhang','xu']
age = [1,2,3]
print(id(names),id(age))
names += age
print(id(names))

输出:
14222600 14203656
14222600

使用+=,和extend效果一样

names = ['cui','wang','luo','zhang','xu']
age = [1,2,3]
print(id(names),id(age))
names = names + age
print(id(names))

输出:
14157064 14138120
13448072

但是使用+,却是生成一个新的列表

 

9,统计

1的例子已经包含了,names.count('cui')  #统计列表names里面有几个‘cui’

10,排序&翻转(list.sort()    list.reverse())

 1 >>> names
 2 ['cui', 'wang', 'luo', 'zhang', 'xu', 1, 2]
 3 >>> names[-1] = '2'
 4 >>> names[-2] = '1'
 5 >>> names
 6 ['cui', 'wang', 'luo', 'zhang', 'xu', '1', '2']
 7 >>> names.sort()
 8 >>> names
 9 ['1', '2', 'cui', 'luo', 'wang', 'xu', 'zhang']
10 >>> names.reverse()
11 >>> names
12 ['zhang', 'xu', 'wang', 'luo', 'cui', '2', '1']
13 >>> 

注意:排序前必须同一类型,顺序按照ASCII的顺序

补充:原地排序是指按照你指定的顺序排列数据,然后用排序后的数据替换原来的数据,原来的顺序会丢失。list.sort()

     复制排序是指按照你指定的顺序排列数据,然后返回原数据的一个有序副本。原数据的顺序依然保留,只是对一个副本排序。sorted(列表) BIF

>>> a = [1,0,10,7,11,5]
>>> a.sort()
>>> a
[0, 1, 5, 7, 10, 11]
>>>

>>> a = [1,0,10,7,11,5]
>>> b = sorted(a)
>>> a
[1, 0, 10, 7, 11, 5]
>>> b
[0, 1, 5, 7, 10, 11]
>>>

另外:向sort()或sorted()传入参数reverse = true可以按照降序排列数据 

 

11,获取列表元素的下标(list.index)

1 ['zhang', 'xu', 'wang', 'luo', 'cui', '2', '1']
2 >>> names.index('wang')
3 2
4 >>> 

12,清空列表(list.clear())

>>> names
['cui', 'hu', 'zhang', 'wang', 'luo']
>>> names.clear()
>>> names
[]
>>>

13,列表去重(set(list))

>>> names_copy
['cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo', 'cui', 'hu', 'zhang', 'wang', 'luo']
>>> set(names_copy)
{'hu', 'luo', 'cui', 'wang', 'zhang'}
>>> 

14,如何查找一个列表中的重复元素(刚琢磨的,后续改进)

如果 len(names) = len(set(names)),说明列表不包含重复元素,len(list),会显示列表的长度,也就是有多少个元素

names = ['cui','luo','wang','xupin','xupin','hu',1,2,1,2,1]
if len(names) != len(set(names)):
    names_tmp = []
    for n in range(len(names)):
        if names[n] not in names_tmp:
            names_tmp.append(names[n])
        else:
            print('重复元素:',names[n],'索引位置为:',n)
            print('重复元素:',names[n],'索引位置为:',names.index(names[n]))
    else:
        print(names_tmp)
else:
    print('列表不包含重复元素')
输出为:
重复元素: xup 索引位置为: 4
重复元素: xup 索引位置为: 3
重复元素: 1 索引位置为: 8
重复元素: 1 索引位置为: 6
重复元素: 2 索引位置为: 9
重复元素: 2 索引位置为: 7
重复元素: 1 索引位置为: 10
重复元素: 1 索引位置为: 6
['cui', 'luos', 'wang', 'xup', 'hu', 1, 2]

 

五,元组

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

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

>>> age = (1,3,5,7,7)
>>> age
(1, 3, 5, 7, 7)
>>> age.count(7)
2
>>> age.index(7)
3

 

posted @ 2017-04-28 23:52  露似真珠月似弓  阅读(245)  评论(0编辑  收藏  举报