Python开发入门14天集训营-第二章

二进制转十进制

二进制:用 0和1 表示

二进制对应十进制对应计算关系:

     1     1     1    1    1   1   1   1

  128   64   32  16   8   4   2   1

 

第一排的1 和第二排的数字一一对应关系;第一排属于二进制;

第一排的8个1 等于 第二排8个数的总和 255;第二排属于十进制;

来看个例子:

例1:十进制200转成二进制

首先:200-128 = 72  那么 128对应的1 有了

     72 - 64 = 8            那么64 对应的1有了

          8 - 8 =0            那么8 对应的1 有了

那么没有匹配上的怎么办呢,别忘了二进制是由0和1组成的,没有匹配上的 用0  补齐;

那么十进制200对应的二进制就计算出来了,如下图:

例2:二进制10101011转成十进制

首先:先把对应关系写出来:

再来计算:

把所有二进制1对应的值相加起来,所有0对应的十进制忽略不计,所有1对应值的总和就是最终的十进制171。

 

python 求二进制

bin(342)

得出二进制:'0b101010110'

>>> bin(342)
'0b101010110'

 

ASCII码与二进制

文件转二进制

文字--十进制--二进制(这里的十进制:指的是 文字所对应的ASCII码里边所对应的十进制)

计算机容量单位

每个字符由8位二进制组成

每一位0或者1所占的空间单位叫做bit(比特),这是计算机中最小的表示单位

8bit = 1bytes字节,最小的存储单位,1bytes缩写为1B

1KB = 1024B

1MB = 1024KB

1GB =1024MB

1TB = 1024GB

1PB = 1024TB

1EB = 1024PB

1ZB = 1024EB

1YB = 1024ZB

1BB = 1024YB

字符编码的演化

ASCII GB2312 GBK1.0 GB18030 BIG5(台湾繁体)

后来有了:

Unicode(国际标准字符集 万国码 所有字符最少用16位(2个字节)来表示 。2**16 = 65535)

unicode两个作用:

  支持了全球的语言,大家都可以用unicode

  unicode包含了所有语言的映射关系

unicode优点:unicode解决了字符合二进制的对应关系。一个字符用2个空间。

unicode缺点:浪费很多存储空间和网络传输带宽

再后来,有了:

UTF-8(unicode编码的压缩和优化 目前使用最广泛)

UTF-8所有的字符和符号占用字节进行分类:

  ​ascii码中的内容用1个字节保存

  欧洲的字符用2个字节保存

​  东亚的字符用3个字节保存

UTF-16:使用2/4个字节表示左右字符;优先使用2个字节,否则使用4个字节表示。

UTF-32:使用4个字节表示所有字符。

windows系统中文版 默认编码:GBK

Mac OS \ Linux 系统默认编码:UTF-8

总结:UTF是为unicode编码 设计的一种在存储和传输时节省空间的编码方案。

python里使用编码

python2.X

​ 默认ASCII编码,默认不支持中文,支持中文需要加:#_*_ coding:utf-8 _*_    或者  #!encoding:utf-8

python3.X

​ 默认UTF-8编码,默认支持中文,

浮点数和科学计算法、复数

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x109和12.3x108是完全相等的。浮点数可以用数学写法,如1.23,3.14,-9.01,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。

整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。

复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。

浮点数的精确度问题

 ???????????????????????????

列表

问题:如何通过一个变量存储公司所有员工的名字?

列表是什么?

列表是一个数据的集合,集合内可以放任何数据类型,可对集合进行方便的增删改查。

语法:

L1 = []   #定义空列表

列表的方法:

1、创建

​ 方法一:list1 = ["a","b"]  #常用

​ 方法二:list2 = list()    #一般不用这种方法

2、查询

​ 列表的索引(也称下标):

  列表从左到右 下标是 从0开始0 1 2 3...

​  列表从右到左 下标是 从-1开始-1 -2 -3...

​ 查询索引值:

​ list1.index(a)   #index查询找到第一个a程序就不走了,

​ list1[0]   #通过a的索引 得出a

​ list1[-1]  #通过b的下标 得出b

 

​ 当list1 = [1,2,3,4,4,4,4,4,4] 列表里出现元素相同时,统计相同次数

​ list1.count(4)   #统计得出:6   代表列表有6个4

3、切片

切片:通过索引(或下标)截取列表中一段数据出来。

​ list1 = [1,2,3,4,4,4,4,4,4]

​ list1[0:2]   #得出 [1,2] ,列表切片顾头不顾尾,也可成list1[:2]

​ list1[-5:]   #得出[4,4,4,4,4],取最后5个元素,只能从左往右取

​ 按步长取元素:

​ list1 = [1,2,3,4,5,6,1,2,3,4,5]

​ list1[:6:2]   #得出:[1, 3, 5]   :2 代表步长 ,每隔两步取一个元素

​ list1[::2]   #得出:[1, 3, 5, 1, 3, 5]  在列表所有元素中,每隔2步取一个数

4、增加

​ list1 = ["a","b","c"]

​ list1.append("d")   #追加d到列表list1的最后 结果:['a', 'b', 'c', 'd']

​ list1.insert(1,"aa")   #插入aa到列表下标为1的之前   得出结果:['a', 'aa', 'b', 'c', 'd']

5、修改

​ list1[1] = "bb"   #直接给对应位置赋值,即是修改 结果:['a', 'bb', 'b', 'c', 'd']

​ 批量修改

​ 把['a', 'bb', 'b', 'c', 'd']里的前两个元素替换掉

​ list1[0:2] = "boy"   #结果:['b', 'o', 'y', 'b', 'c', 'd']

6、删除

​ list1 = ['b', 'o', 'y', 'b', 'c', 'd']

​ list1.pop()   #默认删除最后一个元素 d

​ list1.remove("o")   #删除元素O remove只能一个一个删除

​ list1.remove(0)   #删除下标为0的元素 b
del list1[0]   #删除下标为0的元素 del是一个全局删的方法
del list1[0:2]   #del可以批量删除

7、for循环列表

​ list1 = [1,2,3,4,5,6,1,2,3,4,5]

​ 使用for循环 循环列表list1里边的元素

View Code
​ range(10)   #生成0到10 的数字

使用for循环生成0 - 10 的数字

View Code
8、排序

​ list1 = ["1","5","3","a","b","f","c","d","A","C","B"]

​ list1.sort()

 结果:['1', '3', '5', 'A', 'B', 'C', 'a', 'b', 'c', 'd', 'f']

 

​ 排序是按照ASCII码对应排序。

​ 反转

​ list1.reverse()

 结果:['f', 'd', 'c', 'b', 'a', 'C', 'B', 'A', '5', '3', '1']

9、两个列表拼一块

​ 方法一

​ list1 = [1,2,3,4,5]

​ list2 = [6,7,8,9]

​ list1 + list2 结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]

​ 方法二

​ list1.extend(list2)   #把列表2扩展到list1中

 结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]

10、clear

​ 清空列表

 list2.clear()   #清空list2

11、copy

​ 浅copy

​ 复制列表 list2 = list1.copy()

​ 当列表只有一层数据,没有列表嵌套列表的情况下,复制后的列表和原来的列表是完全独立的。

​ 当列表有多层嵌套的时候,列表嵌套里边的列表的内容是和 原有列表是共享的。

​ 所以这个叫做:浅copy list1.copy()

​ 深copy

​ 需要借助python模块

​ import copy

​ list2 = copy.deepcopy(list1)

​ 深copy 后,新的列表和旧的列表,不管有没有列表嵌套列表,都是完全独立的个体。

 

可以通过查看列表名对应的内存地址分辨 两个列表是否独立

​ 查看python解释器里边的内存地址:id(变量名)
View Code

 

列表的特点

1、可以重复的

2、有序的

列表练习题

1、创建一个空列表,命名为names,往里面天添加old_driver,rain,jack,shanshan,peiqi,black,black_girl元素
names = []
names.append("old_driver")
names.append("rain")
names.append("jack")
names.append("shanshan")
names.append("peiqi")
names.append("black")
names.append("black_girl")
print(names)    #['old_driver', 'rain', 'jack', 'shanshan', 'peiqi', 'black', 'black_girl']

2、往names列表里black_girl前面插入一个alex
names.insert(names.index("black_girl"),"alex")
print(names)    #['old_driver', 'rain', 'jack', 'shanshan', 'peiqi', 'black', 'alex', 'black_girl']

3、把shanshan的名字改成中文 姗姗
names[names.index("shanshan")] = "姗姗"
print(names)    #['old_driver', 'rain', 'jack', '姗姗', 'peiqi', 'black', 'alex', 'black_girl']

4、往names列表里rain的后面插入一个子列表[oldboy,oldgirl]
names.insert(names.index("rain"),["oldboy","oldgirl"])
print(names)    #['old_driver', ['oldboy', 'oldgirl'], 'rain', 'jack', '姗姗', 'peiqi', 'black', 'alex', 'black_girl']

5、返回peiqi的索引
print(names.index("peiqi"))     # 5

6、创建新列表[1,2,3,4,2,5,6,2],合并入names列表
list1 = [1,2,3,4,2,5,6,2]
names = names + list1
print(names)    
结果 :
['old_driver', ['oldboy', 'oldgirl'], 'rain', 'jack', '姗姗', 'peiqi', 'black', 'alex', 'black_girl', 1, 2, 3, 4, 2, 5, 6, 2]

7、取出names列表中索引4-7的元素
print(names[4:7])   #['姗姗', 'peiqi', 'black']

8、取出names列表中索引2-10的元素,步长为2
print(names[2:10:2])    #['rain', '姗姗', 'black', 'black_girl']

9、取出names列表中最后3个元素
print(names[-3:])       # [5, 6, 2]

10、循环names列表,打印每个元素的索引值,和元素
count = 0
for i in names:
    print(count,i)
    count += 1

#另一方法:enumerate(names) 枚举
print(enumerate(names)) #直接取索引
for i in enumerate(names):
    print(i)    #打印的值是一个小列表

for index,i in enumerate(names):
    print(index,i)    #打印的值不是列表了

11、循环names列表,打印每个元素的索引值和元素,当索引值为偶数,把对应的元素改成-1
方法一
count = 0
for i in names:
    if count%2 == 0 :   #代表偶数
        names[count] = -1
        print(count,i)
        count += 1
    #     continue
    else:
        print(count,i)
        count += 1
print(names)

方法二、
for index,i in enumerate(names):
    if index % 2 == 0:  # 代表偶数
        names[index] = -1
        print(index,i)    #打印的值不是列表了
print(names)

12、names里有3个2,请返回第2个2的索引值,不要人肉数,要动态找(提示,找到第一个2的位置,在此基础上再找第2个)

方法一:
count = 0
for i in names[names.index(2)+1:]:
    if i == 2:
        print(names.index(2)+1+ count )
        break
    count += 1
方法二
first_indext = names.index(2)   #第一个2的索引值
new_list = names[first_indext+1:]   #从第一个2的位置+1 开始切片,重新赋值给新的列表
second_index = new_list.index(2)    #查询2 在新的列表中的索引值
last_index = first_indext + second_index +1 #第一个的索引值+ '第二个的索引值+切片时候的+1'
print("第二个2 的index:",last_index)

13、现有商品列表如下:
products = [ ['Iphone8',6888],['MacPro',14800], ['小米6',2499],['Coffee',31],['Book',80],['Nike Shoes',799] ]
需打印出这样的格式
---------商品列表----------
0. Iphone8    6888
1. MacPro    14800
2. 小米6    2499
3. Coffee    31
4. Book    80
5. Nike Shoes    799

方法一、
print("---------商品列表----------")
for Index, i in enumerate(products):
    print("%s %s    %s" % (str(Index) + ".", i[0], i[1]))




14、写一个循环,不断的问用户想买什么,用户选择一个商品编号,就把对应的商品添加到购物车里,最终用户输入q退出时,打印购物车里边的商品列表
shopping_car = []
while True:
    print("---------商品列表----------")
    for Index, i in enumerate(products):
        print("%s %s    %s" % (str(Index) + ".", i[0], i[1]))

    want = input("您想要买什么,请输入对象商品编号: 例<2>,输入<q>退出 >>")
    if want.isdigit():
        want = int(want)
        if want > len(products)-1:
            print("输入商品编号错误,没有该编号!!")
        else:
            shopping_car.append(products[want])
            print("已经将%s加入购物车"%products[want])
    elif want == "q":
        if len(shopping_car) > 0:
            print("您已购买以下商品:")
            for Index,i in enumerate(shopping_car):
                print("%s %s    %s" % (str(Index) + ".", i[0], i[1]))
        break
    else:
        print("输入不正确!")
        continue


知识补充:

判断字符串是否是一个数字
"33".isdigit()

查看列表的长度
len(names)

break 退出也可以用标志位 来设置True False 进行循环判断退出
#标志位
flag = True
while True:
    if xxx:
        pass
    else:
        flag = False    #标志位 设置False 结束循环
View Code

for循环和while循环的区别

​ while可以是死循环

​ for循环是有边界的

数据类型-字符串

字符串是一个有序的字符的集合,用于存储和标识基本的文本信息,

一对单引号、双引号、三引号中间包含的内容称之为字符串。

创建

s = “abcd”

特点

有序

不可变(一旦声明,不能修改)

字符串的基本方法

s = "abcd"
print(s.swapcase())     #都变成大写字母

print(s.capitalize())   #都变成首字母大写

print(s.center(50,"*"))   #打印变量s的字符串 指定长度为50,字符串长度不够的用*号补齐

print(s.count("a",0,5))     #统计字符串a在变量里有几个;0,5代表统计范围是下标从0-5的范围

print(s.endswith("!"))      #是否是以什么结尾的。

print(s.startswith("a"))    #判断以什么开始

#插播知识
#"a\tb"  字符串中间的\t 被认为是tab 是4个或者8个空格
#整体意思是:a 有一个tab 然后 又有一个b

s = "a  b"
print(s.expandtabs(20))  #相当于在a和b中间的tab长度变成了20个字符,交互模式可看出效果

s.find("a",0,5)     #查找字符串,并返回索引

s.format()          #字符串格式化
s1 = "my name is {0},i am {1} years old"
print(s1)
print(s1.format("aaa",22))  #分别把{0}替换成aaa  {1}替换成22
#也可以写成如下
s1 = "my name is {name},i am {age} years old"
s1.format(name="aaa",age = 22)  #字典形式赋值

#s.format_map()  #后续补充


print(s.index("a"))     #返回索引值

print(s.isalnum())      #查看是否是一个阿拉伯字符 包含数字和字母

print(s.isalpha())      #查看是否是一个阿拉伯数字 不包含字母

print(s.isdecimal())    #判断是否是一个整数

print(s.isdigit())      #判断是否是一个整数

print(s.isidentifier())     #判断字符串是否是一个可用的合法的变量名

print(s.islower())      #判断是否是小写字母

print(s.isnumeric())    #判断只有数字在里边

print(s.isprintable())  #判断是否可以被打印,linux的驱动不能被打印

print(s.isspace())      #判断是否是一个空格

print(s.istitle())      #判断是否是一个标题   每个字符串的首字母大写  Hello Worlld

print(s.isupper())      #判断是否都是大写

# s.join()      
name = ["a","b","1","2"]
name2 = "".join(name)   #列表转成字符串,把列表里边的元素都join到字符串中
print(name2)        #得出ab12

#s.ljust
s = "Hello World"
print(s.ljust(50,"-"))  #给字符串从左往右设置长度为50,字符串长度不够用 - 补充

print(s.lower())        #字符串都变成小写

print(s.upper())        #变大写

print(s.strip())        #脱掉括号里边的,可以是空格 换行 tab ...

s.lstrip()              #只脱掉左边的空格
s.rstrip()              #只拖点右边的空格

# s.maketrans()           #
str_in = "abcdef"       #必须是一一对应
str_out = "!@#$%^"      #必须是一一对应
tt = str.maketrans(str_in,str_out)  #生成对应表,就像密码表一样
print(tt)
#结果:{97: 33, 98: 64, 99: 35, 100: 36, 101: 37, 102: 94}

print(s.translate(tt))  # s.translate方法调用 加密方法tt 给 s的字符串加密
#结果:H%llo Worl$

# s.partition()
s = "Hello World"
print(s.partition("o")) #把字符串用 从左到右第一个o把 字符串分成两半
#结果:('Hell', 'o', ' World')

s.replace("原字符","新字符",2)     #字符串替换,也可以写换几次 默认全换,可以设置count次数

s.rfind("o")       #查找最右边的字符,也有开始和结束

print(s.rindex("o") )   #查找最右边的字符的索引值

s.rpartition("o")       #从最右边的字符开始 把字符串分成两半

s.split()               #已括号里边的把字符串分成列表,括号里可以是空格、等字符来分成列表

s.rsplit()              #从最右边以 某字符 来分开字符串

s.splitlines()          #设置以换行的形式 把字符串分成列表

print(s.swapcase())       #字母换成相反的大小写,大的变成小,小的变成大
#结果“:hELLO wORLD
#原来的“hello World”

s.title()               #把字符串变成title格式  Hello World

s.zfill(40)             #把字符串变成40,字符串不够,从左往右用0 补齐


必须要会的
 isdigit
 replace
 find
 count
 index
 strip
 split
 format
 join
 center
View Code

元组

元组跟列表差不多,也是存一组数,只要一旦创建,就不能修改,所以也叫只读列表。

语法

names = ("abc","ABC")

特点

有序的

不可变的,如果元组中还包含其他可变元素,这些可变元素可以改变

功能

index  索引

count  统计

切片  [0,5]

使用场景

显示的告知别人,此处数据是不可修改的

数据库连接配置信息等

hash函数

hash,一般翻译为“散列”,也有直接翻译为“哈希”的,就是把任意长度的输入,通过散列算法,变成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不通的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值,简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

特征

hash值的计算过程是依据这个值的一些特征计算的,这就要求被hash的值必须固定,因此被hash的值必须是不可变的。

(不能保证输出的数据唯一的,容易造成冲突)

用途

文件签名

md5加密

密码验证

语法

>>> hash("abc")
-6784760005049606976
>>> hash((1,2,3))
2528502973977326415

数据类型分类

不可变类型

  数字

  字符串

  元组

可变类型

  列表

  字典

  集合

 

字典

案例:如何在一个变量存储公司每个员工的个人信息?

names = [
  ["aaa",22,15111111111]
  ["bbb",33,15611111111]
  ["ccc",44,18611111111]
  ...
]
???怎么查找 ?太麻烦了吧  

字典是一种key :value的数据类型,使用就像我们上学使用的字典,通过笔画、字母来查找对应页的详细信息

语法


定义空字典
info = {}

info = {
  "student01":"aaa",
  "student02":"bbb",
  "student03":"ccc"
}
查询:
print(info["student01"])
输出:aaa

特点

key:value 结构

key 必须可hash、必须是不可变数据类型、必须唯一

value 可存放任意多个值、可修改、可以不唯一

无序的 (通过key查询)

字典查找速度快,为什么快?

因为:字典把每个key通过hash变成一个数字(数字是按照ASCII码表进行排序的),查询变快了,

list1 = ["122","-343434","434","A","666","777","C","665666","7773777","33"]
list1.sort()  #排序
print(list1)  #打印list1
#结果: ['-343434', '122', '33', '434', '665666', '666', '777', '7773777', 'A', 'C']

方法

# 字典方法
info = { 
    "student01":"aaa" , 
    "student02":"bbb",
    "student03":"ccc"
}

# 增加
info["student04"] = "ddd"
info["student05"] = "eee"
info["student06"] = "fff"

# 查询
# 判断student01在不在info字典里
print("student01" in info    )   # 返回True

print(info.get("student01"))    # 返回aaa,没有返回None

info["student01"]   # 获取对应的value ,如果没有这个key 就报错,所以一般用get


# 删除
print(info.pop("student01"))  # 删除key

print(info.popitem())       # 随机删除一个key

del info["student02"]   # 删除的key ,如果没有删除的key 就报错 KeyError: 'student01'


info.clear()    # 清空字典

# 多级字典嵌套
dic1 = {"aaa": {"aa": 11}, "bbb": {"bb": 22}}

# 其他方法
info = {
    "name1": [22, "it"],
    "name2": [24, "hr"],
    "name3": 33
}

info2 = {
    "name1": 44,
    "name4": 33,
    1: 2
}

info.keys() # 打印所有的key

info.values()   # 打印所有的value

info.items()    # 把字典转成一个列表

info.update(info2)   # 把两个字典合成一个,如果有重复的key ,info2里边的重复key会覆盖info里边的key

info.setdefault("student07","abcdef")   # 设置一个默认的key:value ,
# 如果info字典里没有key student07 ,那么info字典里有添加 student07:abcdef
# 如果info字典里已经手动添加了student07的key value,那么这里的student07:abcdef 就不起作用

print(info.fromkeys(["name1","name2"],"aaa") )    # 从一个可迭代的对象中批量生成key和相同的value


# 字典的循环
# 高效循环
for k in info:
    print(k,info[k])    # 打印key value

# 另外一种方法 低效
for k,v in info.items():    # 先把字典转成列表,在循环,所以低效
    print(k,v)

'''
输出:
name1 44
name2 [24, 'hr']
name3 33
name4 33
1 2
student07 abcdef
'''
View Code

 字典练习题

#写代码,有如下字典,按照要求实现每一个功能
dic = {
    "k1":"v1",
    "k2":"v2",
    "k3":"v3"
}
#1、请循环遍历出所有的key
for k in dic:
    print(k)

#2、请循环遍历出所有的value
for k in dic:
    print(dic[k])

#3、请循环便利出所有的key 和value
for k in dic:
    print(k,dic[k])

#4、请在字典中添加一个键值对 "k4":"v14",输出添加后的字典
dic["k4"] = "v4"
print(dic)
#结果:{'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}

#5、请删除字典中键值对"k1","v1" 并输出删除后的自恋
dic.pop("k1")
print(dic)
#结果:{'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}

#6、请删除字典中的键值“k5”,如果字典中不存在键“k5” ,则不报错,返回None
# dic.pop("k5") #返回None

#7、请获取字典中“k2”对应的值
print(dic.get("k2"))

#8、请获取字典中“k6”对应的值,如果键“k6”不存在,则不报错,并且让其返回None
print(dic.get("k6"))    #返回None

#9、现有dic2 = {"k1":"v111","a":"b"} 通过一行操作使 dic2 ={'k1': 'v1', 'a': 'b', 'k2': 'v2', 'k3': 'v3'}
dic2 = {"k1":"v111","a":"b"}
dic = {"k1":"v1","k2":"v2","k3":"v3"}
dic2.update(dic)
print(dic2)

#10、组合嵌套题,写代码,有如下列表,按照要求实现每一个功能
lis = [["k",["que",20,{"k1":["tt",3,"1"]},89],"ab"]]
#10.1 将列表lis中的“tt”变成大写(用两种方式)
lis[0][1][2]["k1"][0] = "TT"
print(lis)
lis[0][1][2]["k1"]= ["TT",3,"1"]
print(lis)
#10.2 将列表中的数字3变成字符串“100”(用两种方式)
lis[0][1][2]["k1"][1] = "100"
print(lis)
#10.3 将列表中的字符串“1”变成数字101(用两种方式)
lis[0][1][2]["k1"][2] = 101
print(lis)

#11、按照要求实现以下功能
#现有一个列表li = [1,2,3,"a","b",4,"c"],有一个字典(此字典是动态生成的,你并不知道他里面偶多少键值对,所以用dic = {}模拟此字典);现在需要完成这样的操作,如果该字典没有“k1”这个键,那就创建这个“k1”和其对应的值(该键对应的值设置为空列表),并将列表li中的索引位为奇数对应的元素,添加到“k1”这个键对应的空列表中。如果该字典中有“k1 ”这个键,且k1对应的value是列表类型,那就将列表li中的索引位为奇数对应的元素,添加到“k1”这个键对应的值中。
li = [1,2,3,"a","b",4,"c"]

dic = {}
if "k1" not in dic :
    dic["k1"] = []
    for i in li:
        if li.index(i)%2 == 0:
            pass
        else:
            dic["k1"].append(i)
else:
    for i in li:
        if li.index(i)%2 == 0:
            pass
        else:
            dic["k1"].append(i)

print(dic)
View Code

 

集合

如何找出同时买了iphone7和iphone8的人

iphone7 = ["alex","rain","jack","old_driver"]

iphone8 = ["alex","shanshan","jack","old_boy"]

#方法
both_list = []
for name in iphone8:
    if name in iphone7:
        both_list.append(name)
print(both_list)
这个方法很麻烦,需要写两个循环,而集合可以更方便来实现。

 

集合是一个无序的,不重复的数据组合。

作用

去重,把一个列表变成集合,就自动去重了。

关系测试,测试两组数据之间的交集、差集、并集等关系

语法

s = {} #如果为空,就是字典

s = {1,2,3,4} #就成了集合 set

s = {1,2,3,4,1,2} #有重复数据,显示结果就直接去重{1, 2, 3, 4}

列表转成给一个字典

l = [1,2,3,4,1,2]

l2 = set(l)

方法

#集合方法
s = {1,2,3,4,5}     #定义一个集合

#增加
s.add(6)
print(s)    #{1, 2, 3, 4, 5, 6}

#删除

#随机删除
s.pop()
print(s)    #{2, 3, 4, 5, 6}

#指定删除,如果不存在,就报错
s.remove(6)
print(s)    #{2, 3, 4, 5}

#指定删除,如果不存在,不报错
s.discard(6)
print(s)

#联合其他集合,可以添加多个值
s.update([7,8,9])
print(s)    #{2, 3, 4, 5, 7, 8, 9}

#清空集合
s.clear()


#集合的关系测试
iphone7 = {"alex","rain","jack","old_driver"}
iphone8 = {"alex","shanshan","jack","old_boy"}

#交集
print(iphone7.intersection(iphone8))
print(iphone7 & iphone8)
输出:
{'jack', 'alex'}
{'jack', 'alex'}

#差集
print(iphone7.difference(iphone8))
print(iphone7 - iphone8)
输出:
{'rain', 'old_driver'}
{'rain', 'old_driver'}

#并集 把两个列表加起来
print(iphone7.union(iphone8))
print(iphone7 | iphone8)
输出:
{'rain', 'jack', 'old_driver', 'alex', 'shanshan', 'old_boy'}
{'rain', 'jack', 'old_driver', 'alex', 'shanshan', 'old_boy'}

#对称差集   把不交集的取出来
print(iphone7.symmetric_difference(iphone8))
输出:
{'rain', 'old_driver', 'shanshan', 'old_boy'}

s = {1,2,3,4}
s2 = {1,2,3,4,5,6,}
#超集 谁是谁的父集
print(s2.issuperset(s))   #s2是s的父集
print(s2 >= s)
输出:
True
True

#子集
print(s.issubset(s2)) #s是s2的子集
print(s <= s2)
输出:
True
True

#判断两个集合是否不相交
print(s.isdisjoint(s2))
输出:
False    #代表两个集合是相交的

s = {1,2,3,-1,-2}
s2 = {1,2,3,4,5,6}
s.difference_update(s2)  #求出s和s2 的差集,并把差集 覆盖给 s
print(s)
结果:{-2, -1}

s.intersection_update(s2)    #求出s和s2的交集,并把交集 覆盖给 s
print(s)
print(s2)
结果:
{1, 2, 3}
{1, 2, 3, 4, 5, 6}
View Code

 

16进制运算

二进制 0 1

十进制 0 1 2 3 4 5 6 7 8 9

八进制0 1 2 3 4 5 6 7

十六进制 0123456789ABCDEF

十进制转8 16的语法

oct(1)   #得出“0o1”   0o 代表八进制(很少用了)

hex(1)   #得出"0x1"   0x代表16进制(还经常在用) 或者后缀是BH

为什么要用16进制? 本质上还是二进制。

16进制方便看

由于字节(byte)在计算机内部出现的频率较高,如果可以使用一种简洁的方式将它的内在含义准确表达出来,将会给我们带来很多方便。
选择十六进制,是因为8位二进制的数字可以方便的转换为2个十六进制的数字。一个字节能且只能由一对十六进制来表示,比如10110110可以表示为B6。
如果使用4进制的话则需要使用4个数字来表示一个字节,不够简洁;使用8进制的话,最靠左的8进制数是由2位二进制数字来表示的,相比于使用16进制有些美中不足。

 

16进制转二进制

var = input("请输入十六进制:")
b = bin(int(var, 16))
print(b)
#输出:
0b100100011

补充知识:

chr(97)   #查看97在ascii里边对应的值

 

字符怎么存到硬盘上的

无论以什么编码在内存里显示字符,存到硬盘上都是二进制。

ascii编码(美国):
    l   0b1101100
    o   0b1101111
    v   0b1110110
    e   0b1100101
GBK编码(中国):
    老   0b11000000 0b11001111
    男   0b11000100 0b11010000
    孩   0b10111010 0b10100010
 
Shift_JIS编码(日本):
    私   0b10001110 0b10000100
    は   0b10000010 0b11001101
 
ks_c_5601-1987编码(韩国):
    나   0b10110011 0b10101010
    는   0b10110100 0b11000010
     
TIS-620编码(泰国):
    ฉัน  0b10101001 0b11010001 0b10111001
View Code

区别:

不同编码的二进制是不一样的

要注意:存到硬盘上以何种编码存的,那么读的时候还得以同样的编码读,否则就乱码了。

字符编码的转换

 

在中国写个软件用的是gbk编码写的,那么放在美国的电脑上就乱码了,如果想显示中文,解决办法有:

 

1、让美国人的电脑上都装上gbk编码

 

2、把写的软件编码都改成utf-8

 

第1种方法不可能实现,第2种方法又太费时费力,所以以上两种方法是行不通的。

 

但是 由于所有系统的编码默认都支持unicode,unicode第二大功能是包含了与所有语言的编码映射关系,那么gbk的软件放在美国人的电脑上,加载到内存里,变成unicode编码,中文就可以正常显示了。

 unicode与gbk的映射表:http://www.unicode.org/charts/

下载如下红圈中的han 就行

python3代码执行流程

python3默认文件编码:utf-8(解释器编码)

python3的内存里:全部是unicode

python3执行代码的过程:

1、解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成unicode

2、把代码字符串按照python语法规则进行解释

3、所有的变量字符都会以unicode编码声明

python3代码编码转换过程

写一个实例,python3默认文件编码utf-8

在windows下打印一下,windows的默认编码是gbk

 

看图说明,打印出来的“路飞学城”已经变成了unicode编码,否则打印就乱码了。

 

而在python2里边,默认编码是ASCII编码,那么文件头声明是utf-8的代码,在windows中将显示乱码

执行代码:

python2环境运行乱码了,python3环境运行代码正常显示。

如何在windows上显示正常呢?

  1、字符串以gbk格式显示

  2、字符串以unicode编码

既然python2不会自动把文件编码转成unicode存在内存里,那么python3里自动转肯定是调用了什么方法,那么在python2里我们就手动使用这个方法:

UTF-8 -- >decode解码 --> Unicode
Unicode -- > encode编码 -- > GBK / UTF-8

decode示例:

encode示例:

 

 

总结:

python3

  文件编码默认 :utf-8

  字符串编码:unicode

python2

  文件编码默认:ascii

  字符串编码默认:ascii

  如果文件头声明了utf-8,那字符串的编码是utf-8

  unicode是一个单独的类型

如何验证编码转对了呢?

看上节decode示例

 

utf-8 编码显示"路飞学城" 为12个字节,3个字节为一个中文。

unicode编码显示"路飞学城"为4个字节,

所以:

“路飞学城”的utf-8编码对应映射位置是“\xe8\xb7\xaf\xe9\xa3\x9e\xe5\xad\xa6\xe5\x9f\x8e”,\xe8\xb7\xaf代表路

“路飞学城”的unicode编码对应映射位置是“\u8def\u98de\u5b66\u57ce”,\u8def代表路

接下来我们在unicode对应的映射表里查找:

 

接下来我们在gbk对应的映射表里查找:

“路飞学城”的gbk编码对应映射位置是“\xc2\xb7\xb7\xc9\xd1\xa7\xb3\xc7”,\xc2\xb7代表路。

根据上图16进制计算映射表对应的值:

去掉第一行 128所在的高字节,这个是python的unicode在映射表上表达忽略了高字节,真正映射的时候还是需要高字节对的;

然后分别算出 每一个16进制对应的十进制的和;

最后将4个数组合就是unicode映射表。

 

 

python bytes类型

二进制的组合转换成16进制来表示就称之为bytes类型,即字节类型,它把8个二进制组成一个bytes,用16进制来表示。

在python2里,bytes类型和字符串是本质上时没有区分的。

  str = bytes

  python2 以utf-8编码的字符串,在windows上不能显示,乱码。

  如何在python2下实现一种,写一个软件,在全球各国电脑上 可以直接看?

    以unicode编码写软件。

    s = you_str.decode("utf-8")

    s2 = u"路飞"

  unicode类型 也算字符串

文件头:

python2:以utf-8 or gbk 编码的代码,代码内容加载到内存,并不会被转成unicode,编码依然是utf-8 or gbk。。。

python3:以utf-8 or gbk编码的代码,代码内容加到在内存,会被自动转成unicode。

 

在python3里,bytes类型主要来存储图片、视频等二进制格式的数据

  str = unicode

  默认就支持了全球的语言编码

 

为什么 python2里

默认不支持中文,初期 格局不够,python2的开发者没有想到python会发展这么快,发展这么强大。python2越来越臃肿、不简洁,终于python3解决了这些问题。

 

最后总结,python里只要出现各种编码问题,无非是哪里的编码设置出错了

常见编码错误的原因有:

  1、python解释器的默认编码

  2、python源文件文件编码

  3、终端使用的编码(windows/linux/os)

  4、操作系统的语言设置

本章练习题

#1、请用代码实现:利用下划线将列表的每一个元素拼接成字符串,li=["alex","eric","rain"]
li=["alex","eric","rain"]
s1 = "_".join(li)
print(s1)
#输出alex_eric_rain

#2、查找列表中元素,移除每个元素的空格,并查找以a或A开头并且以c结尾的所有元素。
li = ["alex","aric","Alex","Tony","rain"]
tu = ("alex","aric","Alex","Tony","rain")
dic = {"k1":"alex","k2":"aric","k3":"Alex","k4":"Tony"}

list1 = []
for i in li:
    i = i.strip()
    if i.startswith("a") | i.startswith("A") and i.endswith("c") :
        list1.append(i)
print(list1)

list2 = []
for i in tu:
    i = i.strip()
    if i.startswith("a") | i.startswith("A") and i.endswith("c") :
        list2.append(i)
print(list2)

list3 = []
for i in dic:
    i = dic[i].strip()
    if i.startswith("a") | i.startswith("A") and i.endswith("c") :
        list3.append(i)
print(list3)

#3、写代码,有如下列表,按照要求实现每一个功能
li = ["alex","eric","rain"]

#计算列表长度并输出
print(len(li))      #输出3
#列表中追加元素“seven”,并输出添加后的列表
li.append("seven")
print(li)       #输出:['alex', 'eric', 'rain', 'seven']
#请在列表的第一个位置插入元素“Tony”,并输出添加后的列表
li.insert(0,"Tony")
print(li)       #输出:['Tony', 'alex', 'eric', 'rain', 'seven']
#请修改列表第2个位置的元素为“Kelly”,并输出修改后的列表
li[1] = "Kelly"
print(li)       #输出:['Tony', 'Kelly', 'eric', 'rain', 'seven']
#请删除列表中的元素“eric”,并输出修改后的列表
li.remove("eric")
print(li)
#请删除列表中的第二个元素,并输出删除的元素的值和删除元素后的列表
print(li.pop(1))
print(li)       #输出:['Tony', 'rain', 'seven']
#请删除列表中的第2至4个元素,并输出删除元素后的列表
# li.pop(2,5)   #此处已经只有3个元素了,无法删除第4个元素
# print(li)
#请将列表所有的元素反转,并输出反转后的列表
li.reverse()
print(li)       #输出:['seven', 'rain', 'Tony']
#请使用for、len、range输出列表的索引
for i in range(len(li)):
    print(i)
'''
输出:
0
1
2
'''
#请使用enumrate输出列表元素和序号(序号从100开始)
for index,i in enumerate(li):
    print(index+100,i)
'''
输出:
100 seven
101 rain
102 Tony
'''
#请使用for循环输出列表的所有元素
for i in li:
    print(i)
'''
输出:
seven
rain
Tony
'''

#4、写代码,有如下列表,请按照功能要求实现每一个功能
li = ["hello","seven",["mon",["h","kelly"],"all"],123,446]
#请根据索引输出“kelly”
print(li[2][1][1])
#请使用索引找到“all”元素并将其修改为“ALL”,如li[0][9]...
li[2][2] = "ALL"
print(li)       #输出:['hello', 'seven', ['mon', ['h', 'kelly'], 'ALL'], 123, 446]

#5、写代码,有如下元组,按照要求实现每一个功能
tu = ("alex","eric","rain")
#计算元素长度并输出
print(len(tu))      #输出3
#获取元素的第二个元素,并输出
print(tu[1])        #输出:eric
#获取元组的第1-2个元素,并输出
print(tu[0:2])      #输出:('alex', 'eric')
#请使用for输出元组的元素
for i in tu:
    print(i)
'''
输出:
alex
eric
rain
'''
#请使用for,len,range输出元组的索引:
for i in range(len(tu)):
    print(i)
'''
输出:
0
1
2
'''
#请使用enumrate输出元组元素和序号(序号从10开始)
for index,i in enumerate(tu):
    print(index+10,i)
'''
输出:
10 alex
11 eric
12 rain
'''

#6、有如下变量,请事先要求的功能
tu = ("alex",[11,22,{"k1":"v1","k2":["age","name"],"k3":(11,22,33)},"44"])
#讲述元组的特性
'''
元组的特点:有序的,不可变的
'''
#请问tu变量中的“k2”对应的值是什么类型?是否可以被修改?如果可以,请在其中添加一个元素“Seven”
#“k2”对应的值是:列表,可以被修改

tu[1][2]["k2"].append("Seven")
print(tu)   #输出:('alex', [11, 22, {'k1': 'v1', 'k2': ['age', 'name', 'Seven'], 'k3': (11, 22, 33)}, '44'])
#请问tu变量中的“k3”对应的值是什么类型?是否可以被修改?如果可以,请在其中添加一个元素“Seven”
#“k3”对应的值是元组,元组的元素不可以修改。

#7、字典
dic = {"k1":"v1","k2":"v2","k3":[11,22,33]}
#请循环输出所有的key
for k in dic:
    print(k)
#请循环输出所有的value
for k in dic:
    print(dic[k])
#请循环输出所有的key和value
for k in dic:
    print(k,dic[k])
'''
输出:
k1 v1
k2 v2
k3 [11, 22, 33]
'''
#请在字典中添加一个键值对,“k4”:“v4”,输出添加后的字典
dic["k4"] = "v4"
print(dic)      #输出:{'k1': 'v1', 'k2': 'v2', 'k3': [11, 22, 33], 'k4': 'v4'}
#请在修改字典中“k1”对应的值为“alex”,输出修改后的字典
dic["k1"] = "alex"
print(dic)      #输出:{'k1': 'alex', 'k2': 'v2', 'k3': [11, 22, 33], 'k4': 'v4'}
#请在k3对应额值中追加一个元素44,输出修改后的字典
dic["k3"].append(44)
print(dic)      #输出:{'k1': 'alex', 'k2': 'v2', 'k3': [11, 22, 33, 44], 'k4': 'v4'}
#请在k3对应的值的第1个位置插入一个元素18,输出修改后的字典
dic["k3"].insert(0,18)
print(dic)      #输出:{'k1': 'alex', 'k2': 'v2', 'k3': [18, 11, 22, 33, 44], 'k4': 'v4'}

#8、转换
#将字符串s = "alex" 转换成列表
s = list("alex")
print(s)    #输出:['a', 'l', 'e', 'x']
#将字符串s = "alex" 转换成元组
s = tuple("alex")
print(s)      #输出:('a', 'l', 'e', 'x')
#将列表li = ["alex","seven"] 转换成元组
li = tuple(["alex","seven"])
print(li)       #输出:('alex', 'seven')
#将元组tu = ("Alex","seven")转换成列表
tu = list(("Alex","seven"))
print(tu)       #输出:['Alex', 'seven']
#将列表li = ["alex","seven"]转换成字典且字典的key按照10开始向后递增
li = ["alex","seven"]

dic = {}
count = 10
for v in li:
    dic[count] = v
    count +=1
print(dic)      #输出:{10: 'alex', 11: 'seven'}


#9、元素分类
#有如下值集合[11,22,33,44,55,66,77,88,99,90],将所有大于66的值保存至字典的第一个key中,
#将小于66的值保存至第二个key的值中。
#即:{"k1":大于66的所有制,"k2":小于66的所有制}
dic = {"k1": [],"k2":[]}

for i in [11,22,33,44,55,66,77,88,99,90]:
    if i > 66:
        dic["k1"].append(i)
    elif i < 66:
        dic["k2"].append(i)
print(dic)      #输出:{'k1': [77, 88, 99, 90], 'k2': [11, 22, 33, 44, 55]}

#10、输出商品列表,用户输入序号,显示用户选中的商品
#商品li = ["手机","电脑","鼠标垫","游艇"]
#允许用户添加商品
#用户输入序号显示内容

li = ["手机","电脑","鼠标垫","游艇"]

while True:
    print("---------商品列表----------")
    for index,i in enumerate(li):
        print(index,i)
    print(""
          "\033[32m添加商品用请输入:<add>\033[0m")
    user_input = input("请输入商品序号:")
    if user_input.isdigit():
        user_input = int(user_input)
        if user_input > len(li)-1:
            print("商品不存在")
        else:
            print("您已选中商品:[%s]"% li[user_input])
    elif user_input == "add":
        goods_input = input("请输入你要添加的商品:")
        li.append(goods_input)
    else:
        print("输入格式不正确,请输入商品序号!!")

#11、用户交互显示类似省市县N级联动的选择
#允许用户增加内容
#允许用户选择查看某一个级别内容
#看后续作业增加需求; 4




#12、列举布尔值是False的所有值
print(2>3)
print("abc".isdigit())
print(len(["11","22"]) > 5)

#13、有两个列表
l1 = [11,22,33]
l2 = [22,33,44]

l1 = set(l1)
l2 = set(l2)
#获取内容相同的元素列表
print(l1.intersection(l2))
#获取l1中有,l2中没有的元素列表
print(l1.difference(l2))
#获取l2中有,l3中没有的元素列表
l3 = {}
print(l2.difference(l3))
#获取l1和l2中内容都不同的元素
print(l1.symmetric_difference(l2))

#14、利用for循环和range输出
#for循环从小到大输出1 - 100
# for i in range(1,101):
#     print(i)

#for循环从大到小输出100 - 1
# for i in range(100,0,-1):
#     print(i)

#while循环从大到小输出100 - 1
# count = 100
# while True:
#     print(count)
#     if count == 1:
#         break
#     count -= 1

#while循环从小到大输出1 - 100
# count = 1
# while True:
#     print(count)
#     if count == 100:
#         break
#     count += 1

#15、利用for循环和range输出9*9乘法表
for y in range(1,10):
    for x in range(1,y+1):
        print("%d*%d=%d" % (x, y, x*y),end="|") #end=" " 表示不换行打印,双引号中间是不换行的隔离符号
    print("")  #换行,这里是空格代表换行,

#python2.x 不换行符是在print之后加逗号就行,如:  print (XXX),

# 输出结果:
# 1*1=1|
# 1*2=2|2*2=4|
# 1*3=3|2*3=6|3*3=9|
# 1*4=4|2*4=8|3*4=12|4*4=16|
# 1*5=5|2*5=10|3*5=15|4*5=20|5*5=25|
# 1*6=6|2*6=12|3*6=18|4*6=24|5*6=30|6*6=36|
# 1*7=7|2*7=14|3*7=21|4*7=28|5*7=35|6*7=42|7*7=49|
# 1*8=8|2*8=16|3*8=24|4*8=32|5*8=40|6*8=48|7*8=56|8*8=64|
# 1*9=9|2*9=18|3*9=27|4*9=36|5*9=45|6*9=54|7*9=63|8*9=72|9*9=81|

#简写的方法
print('\n'.join([ ' '.join([ "%d*%d=%1s" %(y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)]))
View Code

 

作业

1、三级菜单

需求:

现有省、市、县3级结构,要求程序启动后,允许用户依次选择进入各子菜单

可在任意一级菜单返回上一级

可以在任意一级菜单退出程序

所需知识:列表字典

数据结构:
menu = {
    '北京':{
        '海淀':{
            '五道口':{
                'soho':{},
                '网易':{},
                'google':{}
            },
            '中关村':{
                '爱奇艺':{},
                '汽车之家':{},
                'youku':{},
            }
    },
    '上海':{
    }
}
View Code

 

2、写程序:购物车程序

功能需求:

1、启动程序后,输入用户名密码后,让用户输入工资,然后打印商品列表

2、允许用户根据商品编号购买商品

3、用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒

4、用户可随时退出,退出时,打印已购买商品和余额

5、在用户使用过程中,关键输出,如余额,商品已加入购物车等信息,需高亮显示

扩展需求:

1、用户下一次登录后,输入用户名密码,直接回到上次的状态,即上次消费的余额等的信息,再次登录可继续该买

2、允许查询之前的消费记录

数据结构:
goods = [
    {"name":"电脑","price": 1999},
    {"name":"鼠标","price": 10},
    {"name":"游艇","price": 200},
    {"name":"ipad","price": 888},
    ......
]

 

posted @ 2018-03-13 13:50  506554897  阅读(642)  评论(0编辑  收藏  举报