一、封装和解构

  • 封装

  1. 将多个值用逗号分隔,组合在一起,本质上返回元组   t=1,2
  2. a=4,b=5---->a,b=b,a,右边封装,左边解构
  • 解构

  1. 把线性解构的元素解开,并顺序的赋给其他变量,左边的变量数要和右边一致
  2. lst=[3,5]----a,b=lst----print(a,b)
  3. 非线性解构的set和dict也可以解构,不过字典解构取得是key
  4. a,*b={1,2,3,4}也可以,*X代表的是多个,尽量不贪婪的吃掉,b解构后为列表
  5. 使用*变量名接收,但*不能单独使用
  6. lst=list(range(1,101,2))
  7. head,*mid,tail=lst
  8. *head,tail=lst
  • 丢弃变量

  1. 惯例,约定,不是强行标准
  2. _下划线表示不关心这个变量,加了之后一般都表示不关心,一般用了就表示丢弃变量不使用
  3. lst=[9,6,7,8]----_,*_,tail=lst,其中_只是后面的6,7,赋值即定义
  4. lst=[1,(1,2,4),3]---->_,s,_=lst,*_f=s---->
    _,(*_,s),_=lst      嵌套结构,里面的,依然可以如此使用
  5. JAVA_HOME=/usr/bin取出地址和path路径---->name,path=s.split("=")去掉等号再解构,name,_,path=s.partition("=")用等号分成两部分再解构
  • enumerate,将对象变成index、value的二元组   list(enumerate(“abcdefg”))

二、集set

  • 集合是可变无序不重复的,可以去重

  1. s = set(list(range(10)))正确set里面跟可迭代对象s = set([1,2])
  2. s = {[1,2]}报错
  • 增加元素

  1. add(elem)  增加一个元素到集合中,如果元素存在,则什么都不做(去重)    
    s = {1,2,(1,2,3)}             
    s.add("abc")
  2. update(*others)合并其他元素到set集合中来,可以收集多个可迭代对象(列表也可以)
    s = {1,2,(1,2,3),"abc"}
    s.update({1,2,3})
    s.update({1,3,4}{5,6,1})可以收集多个
  • set删除

  1. remove(elem)移除一个元素,不存在则抛出异常
    s.remove(2)移除2这个值,O(1)    hash值
  2. discard(elem)弃用一个元素
    s.discard(2)移除2这个值,没有不报异常
  3. pop()-->item返回被移除的元素
    移除并返回任意的元素,空集合则报异常
    a = s.pop( )
  4. clear()清空
  • set修改查询

  1. 没有必要修改,删掉再加入
  2. 无法查询
  3. 可迭代所有元素
  4. in和not in可以使用,效率高
  • set和线性结构

  1. set和dict等结构,内部使用hash值作为key,时间复杂度可以做到O(1)
  2. 内部数据必须可hash,不可变类型
  • 全集

  1. 所有元素的集合,例如实数集,所有实数组成的集合就是全集
  • 子集subset和超集superset

  1. 一个集合A所有元素都在另一个集合B内,A是B的子集,B是A的超集
  2. A不等于B,则A是B的真子集,B是A的真超集
  • 集合运算

  • 并集

  1. union(*other)等同于“|”
    a = {1,2,3}   b = {2,3,4}
    a | b---->返回结果,新集合
    a.update(b),修改a,a改变,等同于“|=”就地修改,不返回
    a |= b | {5,6}
  • 交集

  1. intersection(*others)---->等同于&
    a = {1,2,3}   b = {2,3,4}
    a & b 直接返回结果,新集合
    intersection_update(*others)---->等同于&=,就地修改,修改引用方
    a &= b,修改a的集合  a &= b & {1,2}---->2
  • 差集

  1. difference(*others)---->等同于“-”
    a = {1,2,3}   b = {2,3,4}   a-b---->1输出结果,新集合
    difference_update(*others)等同于-=,改变a
  • 对称差集

  1. a | b -a & b = a^b,输出结果,新集合
    与并集不同
    a^=b,直接修改a
  • 大小判断

  1. a<=b,判断a是不是b的子集
    a<b,判断a是不是b的真子集
    a>=b,判断a是不是b的超集
    a>b,判断a是不是b的真超集
  2. isdisjoint(other)表示当前集合和零一个集合没有交集,没有则返回True
  • 习题

  1. 你的好友ABC,他的好友BCD,求共同好友

    1. set = {"A","B","C"}
      set1 = {"B","C","D"}
      print(set & set1)
  2. 微信群消息提醒(xxx不是群里所有人的共同好友)

    1. set = {"A","B","C"}
      set1 = {"B","C","D"}
      set2 = {"D","E","F"}
      m = "H"
      m in set | set1 |set2
  3. 权限判断

三、字典:可变无序,key不重复

  • 字典初始化,定义

  1. d = dict(key = value)
  2. dict(zip(['one', 'two', 'three'], [1, 2, 3]))   映射函数构建字典
  3. dict([('one', 1), ('two', 2), ('three', 3)])    可迭代对象映射字典,迭代对象内必须是二元组
  4. d = {'a':10, 'b':20, 'c':None, 'd':[1,2,3]}
  5. 类方法:d = dict.fromkeys(range(5),0)----0可不写
  • 字典元素的访问

  1. d[key]--------按key访问value,不存在报KeyError
  2. get[key[,default]]--------按key访问,返回value,若无,则返回缺省值,没有缺省值则返回None,default可以随便写,想要什么写什么
  3. setdefault(key[,default])
    返回key对应的value值
    key不存在则添加kv对,value为default,并返回default,如果没有设置,则返回None
  • 字典增加和修改

  1. d = {1:"a",2:"b"}
  2. d[3] = "c"增加   ,d[1] = "d"修改
  3. update([other])-->None
    使用另一个字典的kv,更新本字典
    key不存在则添加,存在则覆盖
    就地修改
    d = {1: 'd', 2: 'b', 3: 'c'} d.update({1:"s",4:"f"})
  • 字典删除

  1. pop(key[,“default”])
    key存在则移除,并返回value d.pop(1,"default")
    不存在则返回给定的default
    default未设置,key不存在则抛出KeyError
  2. popitem()

    1. 移除并返回任意kv对,字典为空,抛出KeyError
  3. clear()清空

  • del语句

  1. a = True
    b = [6]
    d = {'a': 1, 'b': b, 'c': [1,3,5]}
    del a
    del d['c'],删除了一个引用
    del b[0]
    c = b
    del c
    del b
  2. b = d['b']
  3. del a['c']del删除的是名称,引用,而不是对象
  • 字典遍历

  1. 遍历key

    1. for k in d:
      print(k)
      for k in d.keys():
      print(k)
  2. 遍历value

    1. for k in d:
      print(d[k])
      for k in d.keys():
      print(d.get(k))
  3. 遍历kv对

    1. for item in d.items():
      print(item)
      for k,v in d.items():
      print(k, v)
  • defaultdict

  1. ollections.defaultdict([default_factory[, ...]])
    第一个参数是default_factory,缺省是None,它提供一个初始化函数。当key不存在的时候,会调用这个工厂函数生成key对应的value
    from collections import defaultdict
    d1 = {}
    d2 = defaultdict(list)
    for k in "abcde":
        for v in range(5):
            if k not in d1.keys():
                d1[k] = []
                d1[k].append(v)
    print(d1)
    for k in 'mnopq':
        for v in range(3):
            d2[k].append(v)
    print(d2)
  • OrderedDict

  1. collections.OrderedDict([items])
    key并不是按照加入的顺序排列,可以使用OrderedDict记录顺序
    from collections import OrderedDict
    import random
    d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
    print(d)
    keys = list(d.keys())
    random.shuffle(keys)
    print(keys)
    od = OrderedDict()
    for key in keys:
        od[key] = d[key]
    print(od)
    print(od.keys())

解析式生成器

  • 标准库datetime

  1. datetime模块

    1. time.sleep(secs)将调用线程挂起指定的秒数
    2. datetime2 = datetime1 + timedelta
      datetime2 = datetime1 - timedelta
      timedelta = datetime1 - datetime2
    3. 构造方法

    4. total_seconds()返回时间差的总秒数
    5. datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0,minutes=0, hours=0, weeks=0)
      year = datetime.timedelta(days=365)
    6. 类方法strptime(date_string,format),返回datetime对象
      对象方法  strftime(format),返回字符串
      字符串format函数格式化
      import datetime
      dt = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
      print(dt.strftime("%Y-%m-%d %H:%M:%S"))
      print("{0:%Y}/{0:%m}/{0:%d} {0:%H}::{0:%M}::{0:%S}".format(dt))
    7. timestamp()返回一个到微秒的时间戳
      时间戳----格林威治时间,1970年1月1日0点到现在的秒数
      构造方法 datetime.datetime(2016,12,6,16,29,43,79043)
      year、month、day、hour、minute、second、microsecond,取datetime对象的年月时分秒及微秒
      weekday()返回星期的天,0-6(周一到七)
      isoweekday()返回星期的天,1-7
      date()返回日期date对象
      time()返回时间time对象
      replace()修改并返回新的时间
      isocalendar()返回一个三元组(年,周数,周的天)
    8. today()返回本地时区当前时间的datetime对象
      now(tz=None)返回当前时间的datetime对象,时间到微秒,如果tz为None,返回和today()一样
      utcnow()没有时区的当前时间
      fromtimestamp(timesstamp,tz=None)从一个时间戳返回一个datetime对象
    9. 对日期时间时间戳的处理

    10. datetime类

    11. 类方法

    12. datetime对象

    13. 日期格式化

    14. timedelta对象

    15. time

列表解析

  • 生成一个列表,元素0-9,对每一个元素自增1后求平方返回新列表

    • [(i+1)**2 for i in range(1,10)]
    • 列表解析式,提高效率,减少出错,简化代码,可读性增强

    • [i for i in range(20) if i%2==0 or i%3==0]
      [i for i in range(20) if i%2==0 and i%3==0]
      [i for i in range(20) if i%2==0 if i%3==0]
      [(x, y) for x in 'abcde' for y in range(3)]
      [[x, y] for x in 'abcde' for y in range(3)]
      [{x: y} for x in 'abcde' for y in range(3)]
      [(i,j) for i in range(7) for j in range(20,25) if i >4 if j>20]
  • 生成器表达式

    • g =("{:04}".format(i) for i in range(1,11))
      可使用next,来一个个的输出
      延迟计算,只从头到尾输出一次
      返回迭代器,可迭代
      next(g)     for i in g print(i)
      g = ["{:04}".format(i) for i in range(1,11)]这个返回的是可迭代对象,不是迭代器
      it = (x for x in range(10) if x %2)
  • 集合解析式

    • {(x,x+1) for x in range(10)}
      {[x] for x in range(10)}不可以,list不可hash,不能放在集合
  • 字典解析式

        {str(x):y for x in range(3) for y in range(4)}

习题:

1、字典解决重复数字:

number = input(">>>")
numberlist = []
numberdict = {}
for i in number:
    numberlist.append(i)
    if not numberdict.get(i):
        numberdict[i] = 0
    numberdict[i] += 1
print(list(numberdict.items()))

2、

# 随机挑选2个字母组成字符串,挑选一百个,
# 降序输出所有不同的字符串,及重复的次数
import random
strlist = []
strdict = {}
m = bytes(range(97,123)).decode()
for i in range(100):
    strlist.append((random.choice(m)+random.choice(m)))
print(strlist)
for k in strlist:
    if not strdict.get(k):
        strdict[k] = 0
    strdict[k] += 1
print(sorted(strdict.items()))

3、

# 随机一百个数字,范围-1000到1000,升序排序
import random
array = []
randomdict = {}
for i in range(100):
    array.append(random.randint(-1000,1000))
for k in array:
    if not randomdict.get(k):
        randomdict[k] = 0
    randomdict[k]+=1
a = list((randomdict.items()))
print(sorted(a))

4、

# 简单选择排序
numlist = [[1,9,4,5,6,3,7,8,2],[1,2,3,4,5,6,7,8,9],
        [9,8,7,6,5,4,3,2,1],[1,1,1,1,1,1,1,1,1,1]]
numlist1 = numlist[0]
# print(numlist1)
for i in range(len(numlist1)):
    maxindex = i
    for j in range(i+1,len(numlist1)):
        if numlist1[maxindex]<numlist1[j]:
            maxindex = j
    if i != maxindex:
        numlist1[i],numlist1[maxindex] =numlist1[maxindex],numlist1[i]
print(numlist1)
# 一次判断极大和极小值
numlist = [1,8,2,3,5,6,4,7,9]
for i in range(len(numlist)//2):
    maxindex = i
    minindex = -i-1
    for j in range(i+1,len(numlist)-i):
        if numlist[maxindex]<numlist[j]:
            maxindex = j
        if numlist[minindex]>numlist[-j-1]:
            minindex = -j-1
    if i != maxindex:
        numlist[maxindex],numlist[i] = numlist[i],numlist[maxindex]
        if i == minindex or i == len(numlist)+minindex:
            minindex = maxindex
    if -i-1 != minindex:
        numlist[-i-1],numlist[minindex] = numlist[minindex],numlist[-i-1]
print(numlist)
5、
# 行列相等
lst=[[1,2,3],[4,5,6],[7,8,9]]
length=len(lst)
for i in range(length):
    for j in range(i):
        lst[i][j],lst[j][i] = lst[j][i],lst[i][j]
# print(lst)
for i in lst:
    print(i)
lst=[[1,2,3],[4,5,6],[7,8,9]]
for i,row in enumerate(lst):
    for j,col in enumerate(row):
        if i<j:
            lst[i][j],lst[j][i]=lst[j][i],lst[i][j]
print(lst)
# 新建列表
firstlist = [[1,2,3],[4,5,6]]
secondlist = []
m = len(firstlist)
for i in range(m+1):
    secondlist.append([0]*m)
# print(secondlist)
# print(firstlist)
for i in range(m):
    for j in range(m+1):
        secondlist[j][i]=firstlist[i][j]
print(secondlist)
转置矩阵公式
matrix = [[1,2,3],[4,5,6]]
turnmatrix = []
for row in matrix:
    for i ,col in enumerate(row):
        if len(turnmatrix)<i+1:
            turnmatrix.append([])
        turnmatrix[i].append(col)
print(turnmatrix)

6、考试题

# 第一题
number = list({5,10,3,8,6,10,9,15,24,30,27,48,24})
print(sum([i for i in number if i%3==0 and i%4!=0]))
# 第二题
a = '''ftp://ftp.astron.com/pub/file/file-5.14.tar.gz
ftp://ftp.gmplib.org/pub/gmp-5.1.2/gmp-5.1.2.tar.xz
ftp://ftp.vim.org/pub/vim/unix/vim-7.3.tar.bz2
http://anduin.linuxfromscratch.org/sources/LFS/lfs-packages/conglomeration//iana-etc/iana-etc-2.30.tar.bz2
http://anduin.linuxfromscratch.org/sources/other/udev-lfs-205-1.tar.bz2
http://download.savannah.gnu.org/releases/libpipeline/libpipeline-1.2.4.tar.gz
http://download.savannah.gnu.org/releases/man-db/man-db-2.6.5.tar.xz
http://download.savannah.gnu.org/releases/sysvinit/sysvinit-2.88dsf.tar.bz2
http://ftp.altlinux.org/pub/people/legion/kbd/kbd-1.15.5.tar.gz
http://mirror.hust.edu.cn/gnu/autoconf/autoconf-2.69.tar.xz
http://mirror.hust.edu.cn/gnu/automake/automake-1.14.tar.xz
'''
b = a.split("\n",-1)
# for i in range(len(b)):
#     if "ftp" in b[i]:
#         print(b[i])
print([b[i].rsplit("/",1)[1] for i in range(len(b))
       if "ftp" in b[i] and ("gz" in b[i] or "xz" in b[i]) ])
# 第三题
import random
matrix,turnmatrix = [],[]
number = int(input(">>>:"))
for _ in range(number):
    matrix.append([])
    turnmatrix.append([])
for _ in range(number):
    for i in range(number):
        matrix[i].append(random.randrange(1,number**2+1))
        turnmatrix[i].append(0)
print(matrix)
for i in range(number):
    for j in range(number):
        turnmatrix[i][j]=matrix[j][i]
print(turnmatrix)
# 第四题
import datetime
import random
n = datetime.datetime.now().timestamp()
print(["{:03}_{}_{}".format(int(n),random.randint(1,100),""
    .join([random.choice(bytes(range(97,123)).decode())
           for _ in range(8)])) for _ in range(20)])
# 第五题
lst = [29, 30, 37, 22, 59, 75, 79, 41, 61, 75, 75, 78, 63,
       52, 44, 20, 27, 29, 48, 66, 60, 36, 67, 73, 41, 54,
       66, 46, 74, 47, 61, 23, 38, 61, 51, 55, 48, 59, 28,
       68, 65, 74, 73, 58, 29, 31, 53, 31, 61, 22, 44, 33,
       21, 41, 21, 35, 32, 59, 76, 32, 45, 78, 29, 65, 76,
       70, 54, 22, 32, 52, 62, 42, 41, 73, 72, 64, 56, 50,
       40, 64, 41, 47, 68, 73, 27, 69, 64, 21, 78, 57, 61,
       27, 27, 66, 23, 21, 53, 40, 28, 64]
print(sorted(list(set(lst))))
# 列表方法
lst = [29, 30, 37, 22, 59, 75, 79, 41, 61, 75, 75, 78, 63,
       52, 44, 20, 27, 29, 48, 66, 60, 36, 67, 73, 41, 54,
       66, 46, 74, 47, 61, 23, 38, 61, 51, 55, 48, 59, 28,
       68, 65, 74, 73, 58, 29, 31, 53, 31, 61, 22, 44, 33,
       21, 41, 21, 35, 32, 59, 76, 32, 45, 78, 29, 65, 76,
       70, 54, 22, 32, 52, 62, 42, 41, 73, 72, 64, 56, 50,
       40, 64, 41, 47, 68, 73, 27, 69, 64, 21, 78, 57, 61,
       27, 27, 66, 23, 21, 53, 40, 28, 64]
countlist = []
for i in lst:
    if i not in countlist:
        countlist.append(i)
print(sorted(countlist))
# 第六题
lst = [375 ,3.5 ,6 ,20 ,9 ,-20 ,68]
length = len(lst)
for i in range(length):
    count = 0
    for j in range(i+1,length):
        if lst[i]>lst[j]:
            tmp = lst[i]
            lst[i] = lst[j]
            lst[j] = tmp
            count += 1
    if count == 0:
        break
print(lst)
# 第七题
lst = [375 ,3.5 ,6 ,20 ,9 ,-20 ,68]
length = len(lst)
for i in range(length):
    minindex = i
    maxindex = -i-1
    for j in range(i+1,length-i):
        if lst[maxindex]<lst[-j-1]:
            maxindex = -j-1
        if lst[minindex]>lst[j]:
            minindex = j
    if -i-1!=maxindex:
        lst[maxindex],lst[-i-1] = lst[-i-1],lst[maxindex]
        if i == length + minindex:
            minindex=maxindex
    if i != minindex:
        lst[minindex],lst[i] = lst[i],lst[minindex]
print(lst)
# 第八题
number = set([str(i) for i in set(range(10))])
lower = set((bytes(range(97,123)).decode()))
upper = set((bytes(range(65,91)).decode()))
underline = {"_"}
passwordset = set()
password= list(input(">>>"))
for i in password:
    passwordset.add(i)
if 10 <= len(password) <= 15:
    if (passwordset&number and passwordset&lower
        and passwordset&upper and passwordset&underline)!= set():
        print("Right Password")
    else:
        print("Wrong Password")
else:
    print("Wrong Password")
# 第九题
a = """116.226.208.136 - - [28/Apr/2015:09:01:38 +0800] "GET /js/check.js HTTP/1.1" 304 -
59.53.22.67 - - [28/Apr/2015:09:01:38 +0800] "GET /jquery/jquery.datepick.css HTTP/1.1" 304 -
117.93.56.165 - - [28/Apr/2015:09:01:38 +0800] "GET /jquery/jquery-1.4.2.js HTTP/1.1" 304 -
106.39.189.200 - - [28/Apr/2015:09:01:38 +0800] "GET /jquery/jquery.datepick.js HTTP/1.1" 304 -
219.146.71.17 - - [28/Apr/2015:09:01:38 +0800] "GET /jquery/jquery.datepick-zh-CN.js HTTP/1.1" 304 -
111.11.83.162 - - [28/Apr/2015:09:01:38 +0800] "GET /p_w_picpaths/shim.gif HTTP/1.1" 304 -
117.93.56.165 - - [28/Apr/2015:09:01:38 +0800] "GET /p_w_picpaths/button_ok.gif HTTP/1.1" 304 -
111.206.221.200 - - [28/Apr/2015:09:01:38 +0800] "GET /p_w_picpaths/button_cancel.gif HTTP/1.1" 304 -
112.80.144.85 - - [28/Apr/2015:09:01:46 +0800] "GET /user/list.jsp HTTP/1.1" 200 7644
117.148.200.56 - - [28/Apr/2015:09:01:46 +0800] "GET /p_w_picpaths/i_edit.gif HTTP/1.1" 304 -
183.12.49.80 - - [28/Apr/2015:09:01:46 +0800] "GET /p_w_picpaths/i_del.gif HTTP/1.1" 304 -
175.19.57.147 - - [28/Apr/2015:09:01:46 +0800] "GET /p_w_picpaths/button_view.gif HTTP/1.1" 304 -
117.136.63.218 - - [28/Apr/2015:09:05:46 +0800] "GET /user/list.jsp HTTP/1.1" 200 7644
157.55.39.102 - - [28/Apr/2015:09:05:56 +0800] "GET /login.jsp HTTP/1.1" 200 2607
111.206.221.68 - - [28/Apr/2015:09:05:58 +0800] "POST /user_login.action HTTP/1.1" 200 2809
117.93.56.165 - - [28/Apr/2015:09:06:12 +0800] "POST /user_login.action HTTP/1.1" 302 -
223.98.218.205 - - [28/Apr/2015:09:06:12 +0800] "GET /login/home.jsp HTTP/1.1" 200 743
117.136.97.78 - - [28/Apr/2015:09:06:12 +0800] "GET /login/welcome.jsp HTTP/1.1" 200 1142
111.206.221.68 - - [28/Apr/2015:09:06:12 +0800] "GET /login.jsp HTTP/1.1" 200 803
117.93.56.165 - - [28/Apr/2015:09:06:12 +0800] "GET /login/top.jsp HTTP/1.1" 200 2052
111.206.221.68 - - [28/Apr/2015:09:06:13 +0800] "GET /login.jsp HTTP/1.1" 200 1113"""
b = a.split("\n",-1)
# print(b)
lst = [b[i].rsplit("HTTP",1)[0].rsplit(".",1)[1].strip() for i in range(len(b))]
logdict = {}
for i in lst:
    if not logdict.get(i):
        logdict[i] = 0
    logdict[i] += 1
print(logdict)
print("The count of static file is {}".format(logdict["js"]+logdict["css"]))
print("The count of picture file is {}".format(logdict["gif"]))
print("The count of dynamic file is {}".format(logdict["action"]+logdict["jsp"]))