目录

关于这个系列

该系列其它文章

概述

Number(数字)

Int

Float

Complex

Bool

String(字符串)

转义字符

截取

分割

连接

替换

查找

格式化输出

​​​​​​​其它常用操作

Bytes

字节序

字符编码

Bytes和string之间的转换

List(列表)

Tuple(元组)

​​​​​​​Dictionary(字典)

了解hash结构:

字典和列表的区别

深复制和浅复制

Set(集合)

可变数据类型和不可变数据类型

动态类型和静态类型

数据类型转换

数据类型转换支持情况汇总表

转换实例

转换为int

转换为float

转换为bool

转换为complex

转换为string

转换为bytes

转换为list

转换为tuple

转换为set

转换为dict

 


关于这个系列

《最值得收藏的python3语法汇总》,是我为了准备公众号“跟哥一起学python”上面视频教程而写的课件。整个课件将近200页,10w字,几乎囊括了python3所有的语法知识点。

你可以关注这个公众号“跟哥一起学python”,获取对应的视频和实例源码。

这是我和几位老程序员一起维护的个人公众号,全是原创性的干货编程类技术文章,欢迎关注。

 

该系列其它文章

《最值得收藏的python3语法汇总》之数据类型转换

《最值得收藏的python3语法汇总》之函数机制

《最值得收藏的python3语法汇总》之运算符

《最值得收藏的python3语法汇总》之控制语句


概述

 

什么是数据类型呢?前面我们提过,所谓的编程,就是控制一系列的数据去完成我们预设的逻辑或者功能。所以,编程语言首先要定义一系列对“数据”的处理规则。这些处理规则包括:如何存储数据、数据的长度、数据的赋值、数据的读取、数据的显示、数据的比较等等。

不同类型的数据,它们的这些处理规则是不一样的。比如:整数和小数在内存中的存储方式肯定是不一样的;小数有精度的操作,而字符串肯定是没有的。

因此,编程语言需要对我们用到的所有数据进行分类,抽象出一些基本的类型,这就是编程语言定义的数据类型。

不同的编程语言所定义的数据类型其实大同小异,所以你只要理解了python的数据类型,其它编程语言的数据类型也基本都能搞明白。

 

Python3 中定义了七个标准的数据类型:

  1. Number(数字)
  2. String(字符串)
  3. Bytes(字节)
  4. List(列表)
  5. Tuple(元组)
  6. Set(集合)
  7. Dictionary(字典)

下面我们结合一些实例,依次学习这几个标准类型。

 

Number(数字)

数学中的数字包括整数、小数,python中也对应定义了整型(int)和浮点型(float),另外还定义了复数类型(complex)和布尔型(bool)。

  • Int

​​​​​​​它定义了一个整数类型。在C语言中,有很多不同的整型,如下表:

 

不同的类型,有不同的存储大小和取值范围,超出这个范围就会溢出报错。Python明显简化了这一类型,所有的整数类型,不论正负不论大小,全都归一为int类型。Python2还保留了long类型,python3把long类型也去掉了。

我们可以使用不同的方法表示一个int类型的数据,如下所示:

# int 类型int_1 = 100  # 10进制正数
int_2 = -69  # 10进制负数
int_3 = 0x77  # 16进制正数
int_4 = -0x24  # 16进制负数
int_5 = 0o70  # 8进制正数
int_6 = -0o70  # 8进制负数
int_7 = 0b10  # 2进制正数
int_8 = -0b10  # 2进制负数

上面提到了进制,我们先花几分钟了解一下“进制”的概念,看下面这张图:

Python中使用0b开头表示二进制(bin)、0o开头表示八进制(oct)、0x开头表示十六进制(hex)。我们平时用得比较多的,是十进制(dec)、十六进制、二进制,八进制用得比较少。十六进制由于是满16进位,所以大于10的位用字母表示,10-15依次是a-f,不区分大小写。

进制是数值的不同表达方式。不同进制之间可以相互转换,参考下面的实例:


# file: ./6/6_1.py# 进制表达和转换
temp_value = 32904print(" 十进制:{}\n 二进制:{}\n 八进制:{}\n 十六进制:{}\n".format(temp_value, bin(temp_value), oct(temp_value), hex(temp_value)))

输出为:

十进制:32904

 二进制:0b1000000010001000

 八进制:0o100210

 十六进制:0x8088

 

  • Float

​​​​​​​它定义了一个小数类型。在编程语言中,我们习惯把小数叫做浮点数,所以float是浮点型。同样,python简化了浮点型的定义,不论数值大小以及精度,都归一为float类型。Python中有多种方式来表示一个浮点数,如下:

# float 类型float_1 = 17.18  # 正浮点数
float_2 = -17.18  # 负浮点数
float_3 = 7.99E+3  # 科学计数正数
float_4 = -7.99E+3  # 科学计数负数
float_5 = 7.99E-3  # 科学计数
float_6 = 7.99E3  # 科学计数
float_7 = 198.  # 等同于198.0

 

  • Complex

​​​​​​​复数是由一个实数和一个虚数组合构成,表示为:x+yj,其中 x 是实数部分,y 是虚数部分。实数和虚数都是float类型数据。虚数部分必须有后缀j或者J。


# file: ./5/5_2.py# complex 类型
cpx_1 = 123.2+34.6jprint(cpx_1)
print('real: type %s, value %f' % (type(cpx_1.real), cpx_1.real))
print('imag: type %s, value %f' % (type(cpx_1.imag), cpx_1.imag))

输出为:

(123.2+34.6j)

real: type <class 'float'>, value 123.200000

imag: type <class 'float'>, value 34.600000

 

  • Bool

​​​​​​​布尔类型只有两个值,True和False,它们对应值为1和0。Python2中没有真正的布尔类型,使用1和0替代。Python3中明确定义了关键词True和False,注意大小写。


# file: ./5/5_3.py# bool 类型
bool_1 = True
bool_2 = Falseprint(bool_1)
print(bool_2)
print(int(bool_1))  # 强转为int类型
print(int(bool_2))  # 强转为int类型

输出为:

True

False

1

0

 

String(字符串)

 

Python的字符串用单引号或者双引号括起来表示。

字符串由若干个有序字符组成,但是python中的字符串是不能改变的,也就是说我们不能通过索引去改变某个字符的值。比如:str[1]= ‘x’这样的操作是不被允许的。

 

转义字符

 

所谓转义字符,就是在其前面增加右斜杠\后,它并不代表其原本的字符含义,而是转义为另外的含义。比如‘\n’转义后表示一个换行符。

 

Python中用到的转义字符如下表所示:

转义字符

描述

\(在行尾时)

续行符

\\

反斜杠符号

\'

单引号

\"

双引号

\a

响铃

\b

退格(Backspace)

\e

转义

\000

\n

换行

\v

纵向制表符

\t

横向制表符

\r

回车

\f

换页

\oyy

八进制数,yy代表的字符,例如:\o12代表换行

\xyy

十六进制数,yy代表的字符,例如:\x0a代表换行

\other

其它的字符以普通格式输出

# 转义字符
str1 = 'hello,\nworld!'
# 尾部的\是续行符,表示下一行也算作本行的内容。续行符后面不能再有任何字符,包括空格和注释
str2 ='hello,\"world!\"' \'I am Tiger.'print(str1)
print(str2)

输出为:

hello,

world!

hello,"world!"I am Tiger.

对于续行符要注意,它后面不能再有任何字符,包括空格和注释,否则会报错。

 

 

截取

 

字符串截取就是从字符串中获取部分我们想到的字符,这是用得非常多的一个操作。

Python提供了非常灵活简单的字符串截取方式。

 

字符串截取语法如下:

变量[头下标:尾下标]

 

这里的下标,就是指的某个字符在字符串中对应的索引值。支持双向索引。我们还是以“hello,world!”这个字符串为例,其索引如下图所示:

 

正向索引,从0开始,往后递增;反向索引,从-1开始,往前递减。我们只需要明确要截取的子串对应的开始索引和结束索引,即可将其截取出来。

 

这里需要注意一点,python的截取语法,是“前闭后开”的。其截取的子串包含“头下标”对应的字符,但是却不包含“尾下标”对应的字符。这点需要特别注意,容易出错。

 

比如,我们要截取“hello”这个子串。[0:5]、[0:-7]、[-12:5]、[-12:-7],这几种方式可以达到相同的效果。

 

下面列出了一些使用的例子,大家可以参考:

# 字符串截取
str3 = 'hello, world!'
sub_str1 = str3[0:5]  # 截取hello
sub_str2 = str3[-6:-1]  # 截取world
print(sub_str1)
print(sub_str2)
print(str3[5])  # 输出第6个字符
print(str3[:5])  # 输出第6个字符之前的所有字符
print(str3[5:])  # 输出第6个字符及以后的所有字符
print(str3[-5:])  # 输出倒数第5个字符及以后的所有字符

 

分割

 

有时候我们需要对一个字符串依照某种规则进行分割,得到若干个子串。比如,我们以逗号为分割标识,将“hello,world!”分割为两个子串“hello”和“world!”。

 

Python提供了split方法实现字符串分割功能,其语法为:

变量.split("分割标示符号"[分割次数])

 

# 字符串分割 split
sub_str_list =str3.split(',')
print(sub_str_list)

输出为:

['hello', ' world!']

 

Split会返回一个列表结构,这个结构里面存储了分割之后的所有子串。如果找不到分割标识符号,则返回的列表中只有一个元素,就是原始字符串。

 

看下面的例子,我们指定分割次数后会怎么样:

# 字符串分割 split
sub_str_list =str3.split(',')
print(str3.split('o'))
print(str3.split('o', 1))

输出为:

['hell', ', w', 'rld!']

['hell', ', world!']

 

如果我们不指定分割次数,会分割为3个子串。如果我们指定只分割1次,则被分割成了2个子串。

 

Split只能满足一些简单固定的分割规则,对于比较复杂的规则,我们可以采用正则表达式,它的功能就非常强大了。后面我们会专门拿一个章节来讲解正则表达式,这里不展开了。

 

连接

 

我们通常使用下面两种方式来实现字符串的连接:

1、通过加号+实现

2、通过join方法实现

语法: str.join(sequence)

sequence -- 要连接的元素序列,可以是元组或者列表。

 

str1.join([s1,s2, s3])

它的连接结果是:

s1-str1-s2-str1-s3

 

如下实例所示:

# 字符串连接
str3=’ hello, world!’
str4 = ' I am Tiger.'
print(str3 + str4 + " Glad to see you ! ")
print(''.join([str3,str4, " Glad to see you ! "]))
print('**'.join(["aa","bb", "cc"]))  #aa**bb**cc

 

输出为:

hello, world! I am Tiger. Glad to see you !

hello, world! I am Tiger. Glad to see you !

aa**bb**cc

这两种方法实现的效果是一样的,但是他们的实现逻辑却有很大的区别。基于效率的考虑,如果连接的字符串超过2个,建议尽量采用join方法。

加号连接字符串,每连接一个字符串时,系统会分配一次内存,如果连接N个字符串,那么需要分配N-1次内存,性能消耗较大。

而join方法,则是在一开始会计算列表中所有字符串的总长度并一次分配好内存,所以它的性能会高一些。

 

替换

Python使用replace()函数来实现字符串的替换,其语法为:

str.replace(old, new[, max])

 

  1. old -- 将被替换的子字符串。
  2. new -- 新字符串,用于替换old子字符串。
  3. max -- 可选字符串, 替换不超过 max 次

执行成功后,返回替换后的新字符串。

 

比如下面的实例,我们将 “hello,world!”替换为 “hello,python!”:

# 字符串替换str5 = 'python'
print(str3.replace('world', str5))
print(str3.replace('l', 't'))  # 将l替换为t,不限制替换次数
print(str3.replace('l', 't', 2))  # 将l替换为t,限制最多替换2次

输出为:

hello, python!

hetto, wortd!

hetto, world!

 

同样,我们也可以使用正则表达式来实现更加强大的字符串替换功能,正则表达式比较复杂,我们可以先往后放一放,继续下面的学习。

 

查找

Python提供了多种方式来实现字符串的查找,下面我们结合实例分别介绍。

 

1、find()方法

语法 : str.find(sub_str, beg=0, end=len(string))

  • sub_str– 需要查找的子串
  • beg -- 开始索引,默认为0。
  • end -- 结束索引,默认为字符串的长度。

如果查找成功,则返回子串开始的索引值,如果失败,则返回-1。


# 字符串查找str6 = 'hello, python'
sub_str_find = 'll'
sub_str_not_find = 'world'
print(str6.find(sub_str_find))  # ‘ll’匹配到str6的起始索引是2,所以返回2
print(str6.find(sub_str_find, 3))  # 指定从str6的索引为3开始,所以查找不到,返回-1
print(str6.find(sub_str_not_find))  # world字符串不在str6里面,返回-1

 

2、index()方法

 

语法 : str.index(sub_str, beg=0, end=len(string))

  • sub_str– 需要查找的子串
  • beg -- 开始索引,默认为0。
  • end -- 结束索引,默认为字符串的长度。

 

它和find()方法是一样的,只不过如果查找不到,find()方法返回-1,而index()会抛出一个异常(Exception)。关于python异常的处理,我们在后面章节会介绍,这里不需要深究。


print(str6.index(sub_str_find, 3))  # 指定从str6的索引为3开始,所以查找不到,抛出一个异常

抛出异常:

Traceback (most recent call last):

  File "D:/跟我一起学python/练习/5/5_4.py", line 54, in <module>

    print(str6.index(sub_str_find, 3))  # 指定从str6的索引为3开始,所以查找不到,抛出一个异常

ValueError: substring not found

 

正式的代码里面,我们应该对这个异常进行处理,如果不处理程序会报错并退出。

 

3、rfind()方法和rindex()方法

它们的使用方式和find()、index()一样,唯一的区别是它们是反向查找的(从右向左),返回的是子串最后一次出现的位置。

 

可以看看下面的实例:

str7 = 'hello, python, hello'print(str7.find('ell'))  # 正向查找,返回第一次查找到的索引
print(str7.rfind('ell'))  # 反向查找,返回第一次查找到的索引

 

它的输出为:

1

16

反向查找时,返回的是,从右到左匹配到的第一个子串的首字符索引。

需要注意的是,字符串查找返回的都是正向索引的值。这点不要和字符串截取中,反向索引的负数值搞混淆了。

我们同样可以使用正则表达式实现更加强大的字符串查找功能。

 

​​​​​​​格式化输出

Python最常用的输出方式是print(),语法如下。

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

参数说明:

file: 输出的目标文件流,缺省为系统的标准输出.
sep: 插入到不同value之间的字符,缺省是空格符.
end: 最后一个value之后的字符,缺省是\n换行.
flush: 强制刷新标记.

 

我们主要修改第一个参数value,它的表达方式是: “格式化字符串”% 参数列表

如果参数列表是多个,则用小括号括起来,“格式化字符串”% (参数1, 参数2, …)

“格式化字符串”由我们期望输出的字符串和一系列格式化符号组成,下面是格式化符号列表:

   

描述

      %c

 格式化字符及其ASCII码

      %s

 格式化字符串

      %d

 格式化整数

      %u

 格式化无符号整型

      %o

 格式化无符号八进制数

      %x

 格式化无符号十六进制数

      %X

 格式化无符号十六进制数(大写)

      %f

 格式化浮点数字,可指定小数点后的精度

      %e

 用科学计数法格式化浮点数

      %E

 作用同%e,用科学计数法格式化浮点数

      %g

 %f和%e的简写

      %G

 %f 和 %E 的简写

      %p

 用十六进制数格式化变量的地址

 

相匹配的,python提供了一系列辅助指令:

符号

功能

*

定义宽度或者小数点精度

-

用做左对齐

+

在正数前面显示加号( + )

<sp>

在正数前面显示空格

#

在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')

0

显示的数字前面填充'0'而不是默认的空格

%

'%%'输出一个单一的'%'

(var)

映射变量(字典参数)

m.n.

m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

 

下面是一个实例:

# 格式化输出fmt_1ist = [10.2, 99, 'hello']
print('this is example for fmt output \n %.4f, %#0x, %10s' % (fmt_1ist[0], fmt_1ist[1], fmt_1ist[2]))

 

格式化输出本身是比较简单的,大家只要掌握了基本方法,需要的时候查上面的表即可。

 

另外,上面的方式如果参数过多的话,代码的可读性会非常差。Python提供了str.format方法,相对看起来要简单一些。这种方式也提供了很多格式控制符,大家可以自行百度,我们不一一列举了。

# str.formatprint('this is example for fmt output \n {:.4f}, 0x{:x}, {:>10}'.format(fmt_1ist[0], fmt_1ist[1], fmt_1ist[2]))

Python3.6之后又引入了一种新的格式化输出方法:f-string。它比上面方式要简单许多,这里不做介绍,大家可以去百度。

 

​​​​​​​其它常用操作

字符串还有很多操作,我们不可能一一讲解,大家可以在需要使用的时候去查询相关的手册。

 

 

功能

方法

str.strip()

删除字符串两边的指定字符

str.lstrip()

删除字符串左边的指定字符

str.rstrip()

删除字符串右边的指定字符

in

是否包含指定字符串

len(str)

字符串长度

str.lower()

转换为小写

str.upper()

转换为大写

str.swapcase()

大小写互换

str.capitalize()

首字母大写

str.center()

将字符串放入中心位置可指定长度以及位置两边字符

str.count()

统计字符串中出现某个子串的次数

str * num

使用*来复制字符串,num表示复制次数

str.startswith(prefix[,start[,end]])

是否以prefix开头

str.endswith(suffix[,start[,end]]) 

以suffix结尾

str.isalnum()                       

是否全是字母和数字,并至少有一个字符

str.isalpha()                      

是否全是字母,并至少有一个字符

str.isdigit()                      

是否全是数字,并至少有一个字符

str.isspace()                      

是否全是空白字符,并至少有一个字符

str.islower()                      

是否全是小写

str.isupper()                      

是否全是大写

str.istitle()                      

是否是首字母大写的

str.partition()

分割,前中后三部分

str.splitlines()

根据换行执行分割

str.zfill()

返回指定长度的字符串,原字符串右对齐,前面填充0

 

 

 

Bytes

 

Bytes是python3新增的一个数据类型,用于表示一个字节串,它是一个有序的序列。

通常有两种方式来构造一个bytes类型的对象:

1、通过bytes()函数构造

bytes_1 = bytes('hello', 'utf-8')
bytes_2 = bytes([1, 200, 80, 50])

2、通过b后面跟字符串的方式

bytes_3 = b'world'
bytes_4 = b'\x77\x6f\x72\x6c\x64'

我们在print一个bytes类型数据时,python会以/x的格式依次打印每个字节的值,以两位16进制来显示。但是python对于一些字符会直接字符编码转换,所以造成打印出来的结果看起来很混乱,比如:

​​​​​​​bytes_2 = bytes([1, 200, 80, 50])print('bytes_2:', bytes_2)

输出结果为:

bytes_2: b'\x01\xc8P2'

最后两个数值80、50,被转换为了字符P、2,看起来很混乱。

 

这时,我们可以写一个简单的方法,让它不做这种转换:

# bytes 按照16进制输出,强制不ascii转码
def trans(s):return "b'%s'" % ''.join('\\x%.2x' % x for x in s)bytes_2 = bytes([1, 200, 80, 50])print('bytes_2:', trans(bytes_2))

输出结果为:

bytes_2: b'\x01\xc8\x50\x32'

这样我们看到,bytes里面包含了一个一个的字节。

因为我们还没有学函数的概念,所以大家只要知道在输出的时候调用这个方法即可。

 

bytes类型,存储的是一系列的字节,它并不关注这些字节具体表示什么含义(字符、网络数据、图片、音视频等)。Bytes并不约束你如果使用这些字节数据,你可以按照你自己的功能逻辑做任意的转换。这个转换逻辑,不是bytes数据类型的功能范畴。

 

比如:对于字符,通常我们需要对其做一个编码转换,将字节类型转换为有意义的字符串。这个转换规则,就是字符编码,紧接着下一小节我们会介绍字符编码。

 

我们可以看到,bytes类型也是一种序列,所以它的大多数操作方法和String一致。

# 操作方法
print(bytes_3[0: 3])
print(bytes_1 + bytes_3)
print(b'h' in bytes_1)
print(bytes_1.split(b'l'))
print(bytes_1.find(b'll'))
print(bytes_1.replace(b'l', b't'))

输出结果为:

b'wor'

b'helloworld'

True

[b'he', b'', b'o']

2

b'hetto'

是不是和string类型高度一致? bytes类型和string类型的对比如下:

  • string的基本单位是字符,bytes的基本单位是字节;
  • 他们都是属于一种序列,所以对于序列的操作方法,对他们基本都适用;
  • String和bytes都是不可变类型,不能对其元素进行修改。

 

注意,虽然bytes通常会和string一起使用,但是bytes并不只是给string用,它本质上是一个字节串。Bytes适合那种面向二进制流的存储数据,比如图片、视频等多媒体,或者网络通信等二进制报文流。

 

字节序

字节序,顾名思义就是字节存储的顺序。大家可能觉得奇怪,字节不都是“从左到右”依次存储的吗?怎么会有字节序的问题?大家看看下面的例子:

#  author: Tiger,    wx ID:tiger-python# file: ./6/6_2.py# bytes 按照16进制输出,强制不ascii转码
def trans(s):return "b'%s'" % ''.join('\\x%.2x' % x for x in s)# 字节序
byte_1 = 'python'.encode('utf-8')
print(trans(byte_1))print('Big endian: ', hex(int.from_bytes(byte_1, byteorder='big', signed=False)))
print('Little endian: ', hex(int.from_bytes(byte_1, byteorder='little', signed=False)))

输出结果为:

b'\x70\x79\x74\x68\x6f\x6e'

Big endian:  0x707974686f6e

Little endian:  0x6e6f68747970

上面的实例中,我们将bytes类型b’python’强制转换为int类型,在转换过程中分别指定其字节序为big和little。从打印结果可以看出,这两种类型对应的输出结果完全相反。它们对应的就是大端字节序(Big endian,BE)小端字节序(Little endian,LE)

比如我要存储一个字节串:b’\x12\x34\x56\x78’:

大端字节序:从低地址到高地址,依次存储数据字节;

小端字节序:相反,从高地址到低地址,依次存储数据字节。因为我们查看内存通常是由低位地址向高位地址看,所以大端字节序是更加符合我们的习惯的,而小端则相反。

为什么计算机会产生两种不同的字节序呢?

因为字节序是由CPU架构决定,而在计算机技术发展初期,CPU架构的两大阵营X86和PowerPC分别采用了完全相反的两种字节序,X86采用了LE,PowerPC采用了BE。所以,才会导致我们现在需要面对字节序的问题。

 

我们可以下面的方法获取当前cpu的字节序类型:

# 获取当前cpu的字节序类型import sys
print('endian of cur env:', sys.byteorder)

输出为:

endian of cur env: little

我使用的环境是X86的CPU,对应的是小端字节序。

 

如果你的程序只会在本地运行,不会涉及到跨主机(跨不同类型CPU)的操作,那么你不需要关注字节序。反之,你需要特别关注字节序,因为它容易出错。

如果计算机A采用了BE架构的CPU,计算机B采用了LE架构的CPU。我们有一段程序,在计算机A发送一个bytes : b’\x12\x34\x56\x78’给计算机B,那么计算机B解析出来的数据将是bytes : b’\x78\x56\x34\x12’,这就完全错了。

 

在这种跨主机的数据传输中的字节序,我们通常称之为网络字节序,网络字节序和CPU无关,它是网络通信协议定义的一套规范。几乎所有的网络字节序都采用了大端字节序BE。计算机将数据发送给网络协议之前,需要统一转换为网络字节序,同样,接收端的计算机从网络接收到数据后,也会统一将其由网络字节序转换为本机字节序。这样,我们就解决了跨主机的字节序问题。Python的网络编程里面,我们还会涉及到字节序,到时候我们可以回头来看看。

 

字符编码

Python2.x的乱码问题一直被程序员所诟病,虽然Python3.X大体上已经解决了这个问题,但是作为入门python的基础,你还是需要把字符编码问题搞得非常清楚,否则你会被各种“乱码”搞崩溃。下面是引用的知乎上面一个回答,挺有意思:

 

  • 什么是字符编码呢?

我们知道计算机是使用01这样的二进制串来存储数据的,这里的数据不仅仅是数字,而是所有数据,包括图片、视频、音频、文字等等。所以,我们需要有一个规则,来定义这些数据和二进制之间如何转换。

字符编码,就是一套标准(事实上有若干套标准),根据这些标准,我们将字符和二进制双向转换。

最早的字符编码标准,叫做ASCII码。

 

  • ASCII码

计算机技术起源于美国,所以最早的字符编码标准ASCII(American Standard Code for Information Interchange)也是老美根据他们的语言体系制定的。在英语的世界里面,26个小写字母、26个大写字母、若干个标点符号、一些控制符号等就可以表示所有字符。

下面就是全部的ASCII编码,一共就只有256个符号的编码定义:

 

第一列是字符对应的十进制数值,比如001d;

第二列是字符对应的十六进制数值,比如0Ah;

第三列是对应的字符;

0~31还定义了第四列,用于表示一些特殊的控制符,比如008d对应的是退格(Backspace),我们敲键盘的Backspace退格键,就会产生008d这个数值在计算机中传递。

最早 ASCII 只定义了128个字符编码,包括96个显示字符和32个控制符号,一共128个字符,只占用了一个字节8bit位中的低7位。然而随着计算机慢慢普及,一些西欧字符在字符集中无法被表示,于是就有了下面那种扩展ASCII表,将字符集扩展到了256个。

 

  • GB2312\GBK

ASCII码标准的指定可没有考虑中文的问题,于是当计算机在中国以及亚洲国家出现以后,中文编码成了一个问题。为了解决这个问题,我国制定了自己的字符编码标准GB2312(GB-国标)。GB2312收录的汉字基本覆盖了我们使用的绝大多数场景,但是对于繁体字和少数民族文字无法处理。于是后来又制定了GBK标准(K-扩展),GBK在GB2312基础上制定,它除了收录27484个汉字以外,还收录了藏文、蒙文、维吾尔文等少数民族文字。

GBK采用两个字节来表示中文,同时它也兼容ASCII标准,当使用ASCII字符时可以自动转换为一个字节来表示。

 

  • Unicode

不同国家都有自己的语言和文字,如果大家都自己制定自己的字符编码规范,那它们之间如何互通呢?为了解决这个问题,科学家们发明一种统一的字符编码-unicode(UniversalMultiple-OctetCodedCharacterSet,简称UCS),它几乎囊括了人类所有语系字符的编码。Unicode同样也是兼容ascii码的。

Unicode采用2字节编码,这一标准的2字节形式叫做UCS-2。但是我们知道2字节最多只能表示65535个字符编码,这对于一些特殊语系来说是完全不够的,比如中文字符就有几万个。所以,unicode还有一种4字节的形式,叫做UCS-4,它有足够的空间可以定义人类所有的文字符号。

 

  • UTF-8

Unicode是一个字符集,它仅定义了不同符号对应的编码值。但是这个字符该如何存储呢?对于ascii码,我们可以统一采用一个字节来存储不同的字符。Unicode字符也可以这样操作,但这样会带来一个存储效率的问题。

比如字符“a”,它对应的编码是61,一个字节就可以表示。如果我们采用4字节表示,那么有3个字节就浪费掉了。在英语系国家,这种浪费就显得非常严重,接近3/4的存储性能损失,这是不能被接受的。

基于这个原因,出现了各种unicode的实现方法,最著名的是UTF-8。

UTF-8以一个字节(8比特位)为一个编码单位,并且它是变长的。对于不同的unicode字符,它会采用不同的字节长度来存储。这样就可以大大提升存储性能。

 

比如汉字“中”,它的unicode表示和utf-8编码如下:

 

除了UTF-8,还有UTF-16,同理,它是以16比特-2字节为一个编码单位。

 

字符乱码的原因,基本都是字符编码不一致导致的。Python2默认采用ascii码,中文字符默认是不能转换的,所以我们在python2代码中如果涉及中文字符,必须在代码文件一开始就进行字符编码的声明:

# -*-coding:utf-8-*-

Python2的字符编码问题备受诟病。在python3中,默认编码改成了utf-8,所以我们不声明编码类型,也是可以正常支持中文字符的。

字符编码需要端到端保持一致,不管是存储、计算、传输等环节都要设置一致,比如我们代码处理时采用的字符编码必须和数据库存储的编码方式一致。否则很容易出现乱码。

 

Bytes和string之间的转换

Bytes和string之间的转换,其本质就是一个字符编码的过程。Python3提供了encode和decode方式来实现两者之间的灵活转换,其过程如下图:

Encode是字符编码过程,将字符转换为指定的编码,并以bytes类型存储;

Decode则相反,将bytes值转换为对应的字符。

语法如下:

str.encode(encoding='UTF-8',errors='strict')

str.decode(encoding='UTF-8',errors='strict')

 

encoding -- 要使用的编码方式,如"UTF-8"。

errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。

 

下面是一个编解码的例子:

#  author: Tiger,    wx ID:tiger-python# file: ./6/6_3.py# bytes 按照16进制输出,强制不ascii转码
def trans(s):return "b'%s'" % ''.join('\\x%.2x' % x for x in s)# 字符编码
encstr_1 = 'tiger-python'
encbytes_1 = encstr_1.encode('utf-8')
print(trans(encbytes_1))
print(encbytes_1.decode('utf-16'))  # 编码方式不一致,造成乱码
print(encbytes_1.decode('utf-8'))

输出为:

b'\x74\x69\x67\x65\x72\x2d\x70\x79\x74\x68\x6f\x6e'

楴敧⵲祰桴湯

tiger-python

如果编解码的编码方式不一致,则出现乱码。

 

List(列表)

列表是python中非常常用的一个数据结构,它的语法如下:

[item1, item2, item3, …]

由中括号将所有列表元素括起来,不同的元素之间通过逗号分隔。

 

列表中的元素item,支持几乎所有类型的数据,并且同一个列表中的所有元素可以是不同的数据类型。所以列表使用起来会非常灵活。用过C语言数组结构的同学应该知道,数组结构只能存储同一类型的元素,比如整型数组、字符串数组等等。另外,C语言的数组结构一旦初始化之后,是不能动态扩容的。C语言也可以实现列表功能,但它不是C语言的标准数据类型。相比较起来,Python的数据类型要强大和灵活得多。

 

列表本质上是一种序列,前面我们学习的string字符串本质上也是一种序列,还有下一节的tuple元组也是序列。我们来看看序列都有一些什么样的共性呢?

  1. 序列具备索引,正向索引和反向索引,前面字符串截取时我们学习过。
  2. 序列都支持切片(分割、截取)。
  3. 序列具备一些通用的操作(加、乘、检查成员)

 

通过下来的例子我们演示列表的常用操作:


#  author: Tiger,    wx ID:tiger-python
# file: ./5/5_5.py"""
演示列表的操作
"""# list 列表
list_1 = ['hello', 100, ['跟我一起学', 4]]  # 支持不同类型的item,可以嵌套list
list_2 = ['python', '!']print(list_1[0:2])  # 截取的方式和字符串一致
print(list_1[0:-2])
print(list_1[0: 1])
print(list_1[0])print(len(list_1))  # 获取列表的长度# 列表连接
list_3 = list_1 + list_2
print(list_3)# 使用乘法让列表重复n次
list_4 = list_2 * 3
print(list_4)# 判断一个元素是否存在于列表中
print('python' in list_2)  # True# 判断一个元素在列表中出现的次数
print(list_4.count('python'))# 获取列表中最大最小值,求和
list_5 = [1, 2, 4, 10, 90]
print(max(list_5))
print(min(list_5))
print(sum(list_5))# 列表的增删改操作
list_5.append(100)  # 在列表尾增加元素100
print(list_5)list_5.insert(1, 'insert_obj')  # 把元素插入到索引为1的位置
print(list_5)list_6 = ['hello', 'python']
list_5.extend(list_6)  # 在列表后面追加另外一个列表list_5[0] = 200  # 将索引为0的元素修改为200
print(list_5)del list_5[0]  # 删除索引为0的元素
print(list_5)list_5.pop(2)  # 移除索引为2的元素,如果不填写索引值,则默认移除列表最后一个元素
print(list_5)list_5.remove('insert_obj')  # 移除一个元素,注意这里指定的是元素的值。如果列表中有多个相同的值,则只移除第一个匹配项
print(list_5)list_5.clear()  # 清空整个列表
print(list_5)# 列表的排序操作
list_7 = [100, 99, 27, 198, 3]list_7.reverse()  # 列表反向排列
print(list_7)list_7.sort()  # 列表升序排列
print(list_7)list_7.sort(reverse=True)  # 列表降序排列
print(list_7)

由于同一个列表可以支持不同的元素,所以某些列表操作会有一些限制,大家在使用时需要注意。比如一些数值操作,如sum(list),它就无法支持list中包含字符串的情况,因为字符串没法求和。一个比较特殊的操作,最大值max和最小值min,它们支持字符串的比较,那么它们是按照什么规则来比较大小的呢?我们通过一小段代码测试一下。


#  author: Tiger,    wx ID:tiger-python
# file: ./5/5_6.py# max\min 如何比较字符串列表
list_1 = ['a', 'b', 'cat', '跟我一起学python']print(ord('a'), ord('b'), ord('c'), ord('跟'))print(max(list_1))
print(min(list_1))

可以看出,对于字符串列表,是按照元素的首字符对应的ASCII编码值来比较大小的(参考字符编码章节)。如果同一个列表中混杂了数字和字符串,则无法比较,会抛出异常。

 

列表是python中用得最多的标准数据类型,后面我们在讲循环语句时还会介绍如果对列表进行迭代操作。大家应该对列表操作勤加练习,熟能生巧。

 

Tuple(元组)

元组,也是一种序列结构,它和列表非常类似,但是它不能被改变。也就是说,我们不能对元组中的元素进行修改。元组的语法如下:

(item1, item2, item3, …)

由中括号将所有列表元素括起来,不同的元素之间通过逗号分隔。

元组的语法和列表是不是很像,唯一的差别就是它用的小括号,而列表用的中括号。其实不然,元组还有一些特殊的地方,比如下面两个元组的定义:


# file: ./5/5_7.py# 元组的操作
tuple_1 = (1, 2, 100, 'python')
tuple_2 = 'hello', 'python', 100  # python中,未加括号的序列都默认是元组
tuple_3 = (98,)  # 只包含一个元素的元组,需要加上逗号,否则小括号会被认为是运算符

元组的操作和列表几乎是一样的,我们就不一一列出了,大家可以参考列表去练习。

下面我们主要通过实例来看看元组“不可改变”的特性。

# 元组的元素不可改变tuple_4 = (1, 5, 10)
# tuple_4[0] = 3  # 会抛出异常

上面代码运行时会抛出异常:

TypeError: 'tuple' object does not support item assignment

明确提示,元组对象不支持元素的改变。

 

但是,元组元素可以是可变数据类型,如下操作是合法的:

# 元组的元素可以是可变数据类型tuple_5 = (100, 200, [300, 400])
tuple_5[2][0] = 500
print(tuple_5)

 

下图解释了这个过程:

 

我们所谓的元组不可改变,指的是元组本身不可改变。但如果它的元素指向的是一个可变类型,那么这个元素指向的对象是可以改变的。因为整个过程中,元组本身并没有发生改变。

 

再看下面这个例子:

tuple_4 = (1, 5, 10)tuple_4 = (100, 99)
print(tuple_4)

这个例子可以正常运行,并且输出我们预期的正确结果。这说明tuple_4可以被改变吗?还记得我们在前面讲变量的哪些实例吗,我们用同样的方法把tuple_4这个变量对应的内存地址打印出来,看看它究竟发生了什么变化?

tuple_4 = (1, 5, 10)print(id(tuple_4))
tuple_4 = (100, 99)
print(tuple_4)
print(id(tuple_4))

输出结果为:

2812724308608

(100, 99)

2812723061120

我们可以看到,tuple_4在重新赋值后,它对应的内存改变了。这个行为和数字、字符串是不是很像呢?没错,这一类数据类型我们称为“不可变数据类型”。

不可变数据类型对应的内存中的数据是不能被修改的,就像tuple_4一样,它重新被赋值后,实际上是被指向了一块新的内存。原来的那块内存中的数据依然没有改变。

 

​​​​​​​Dictionary(字典)

 

字典,也是Python中使用得比较广泛的一种数据类型。

字典本质上是一种“键值对”(key-value)的集合。“键值对”这种数据的描述方式,更加符合我们对客观世界的认识。客观世界的数据,通常都存在一个名字-key,以及对应的值-value,使用“键值对”可以非常直观简便地表达这些数据。一些数据库技术也是基于键值对的数据存储方式,比如Redis、memcached。“键值对”在大数据领域也有广泛应用。

字典的结构定义和JSON基本一致,两者可以很方便的相互转换。

 

字典的语法如下:

{key1: value1, key2: value2, key3: value3, …}

字典使用大括号{}括起来,每个key-value之间使用逗号分割。Key和value之间使用冒号:分割。

同一个字典里面,key值需要保证唯一,不能重复,并且只能是不可变数据类型(数字、字符串、元组)。

Value不要求唯一,并且可以是任意数据类型。

 

了解hash结构:

字典是一种hash结构,我们有必要简单了解一下hash结构。下图是一个hash结构的示意(这不是python的真正实现):

 

hash是一种数据结构,准确说是一种数据的组织方式。我们在编程中,为了便于数据的操作(增删改查),尤其是性能考虑,会将数据对象以某种特别的方式组织起来,这就是数据结构。除了hash以为,还有数组array、链表sll\dll、平衡二叉树avl、红黑树rbt等。这些数据结构,是编程的算法范畴,不是编程语言的语法范畴,不同的编程语言都可以实现这些数据结构。我们不会重点去讲这些算法的东西,但是作为程序员,你需要理解这些常用的算法。如果有必要我后面可以专门制作一个系列来讲算法。

上图是我工作中最常见的hash结构。它定义了一个hash表(核心是一个定长的数组),用于存hash_key,由于它是数组,所以可以通过索引来查找,性能高。数据对象的key,通过一个hash函数映射到hash_key,这个映射关系可能是n:1,所以存在一个hash_key对应多个数据对象的情况,这就是所谓的hash冲突。为了解决hash冲突,我们在每个hash_key下面挂了一个链表结构,这个就是hash桶(bucket)。Hash冲突越严重,bucket就会越深,从而导致查找性能就越低,所以hash函数是关键。衡量一个hash函数的好坏,是它能否将所有数据对象均衡的散列到不同的hash_key上面的,并且hash函数本身不能耗费太多性能。

 

Hash结构,是各种操作(增删改查)性能都比较高比较均衡的一种结构,使用较广泛。

 

字典和列表的区别

字典不是一种序列,它没有索引,并且是无序的,这一点和列表存在本质区别,大家要注意。

实质上,字典在python的底层实现中,是一种hash索引结构。所以字典结构在查询、新增、删除、修改上面表现出更加优异的时间性能。

 

而列表在python的底层实现中,是一种动态数组结构。该数组元素不会直接保存列表元素的数据,而是存储了列表元素的地址。地址的大小是固定的,所以它可以是一个数组结构。由于它是动态数组(支持resize内存空间),所以也可以支持扩容。同时,数组是连续存储的,所以列表存在索引,是有序的。

下图示意了字典和列表的区别,不同的python版本可能存在差异,但是大体类似。

 

列表采用了指针数组,它是一段连续内存,所以它可以像数组一样去索引的。而字典采用了hash表结构,key值是通过hash函数去命中到一个hash index,所以它只能通过key值去查找。

真正的实现中,不会像我画的这么简单。比如字典的hash表还需要考虑hash散列、hash冲突,但是这些细节并不影响我们理解字典和列表之间的本质区别。对于初学者,不建议大家现在去搞懂这些细节,可以留待后面再去深入理解。

 

下面我们通过一系列实例来熟悉字典的操作:


# file: ./5/5_8.py# 字典
dict_1 = {'name': 'xiaowang', 'age': 20, 'city': 'Chengdu'}
print('name: %s, age: %d, city: %s' % (dict_1['name'], dict_1['age'], dict_1['city']))dict_1['city'] = 'Beijing'
print('name: %s, age: %d, city: %s' % (dict_1['name'], dict_1['age'], dict_1['city']))dict_2 = {}.fromkeys(('name', 'age', 'city'))  # 批量根据key值初始化一个字典
print(dict_2)print(len(dict_1))# 增加键值对
dict_1['sex'] = 'male'
print(dict_1)# 删除键值对
del dict_1['sex']
print(dict_1)# 批量更新
dict_3 = {'name': 'xiaoliu', 'age': 18, 'city': 'Chengdu', 'sex': 'female'}
dict_1.update(dict_3)
print(dict_1)# 判断key是否在字典中存在
print('name' in dict_3)# 获取所有的key
print(list(dict_1.keys()))# 获取所有的value
print(list(dict_1.values()))# 获取所有的(键, 值) 元组列表
print(list(dict_1.items()))# 清空字典
dict_1.clear()
print(dict_1)

 

深复制和浅复制

python提供了copy()方法,用于字典的浅复制(shallow copy)。与浅复制相对应的,还有深复制(deep copy)的概念。我们通过实例来理解一下二者的区别。浅复制和深复制的概念在很多编程语言中都涉及,大家应该理解并举一反三。

# file: ./5/5_10.py# 深复制和浅复制
dict_1 = {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 90, 'shuxue': 100}}
dict_2 = dict_1.copy()print('dict_1:', dict_1)
print('dict_2:', dict_2)# 修改value
print('modify 90->98'.center(64, '-'))
dict_1['score']['yuwen'] = 98
print('dict_1:', dict_1)
print('dict_2:', dict_2)# 深拷贝
print('deep copy'.center(64, '-'))import copy
dict_3 = copy.deepcopy(dict_1)
print('dict_1:', dict_1)
print('dict_3:', dict_3)
print('modify 98->99'.center(64, '-'))
dict_1['score']['yuwen'] = 99
print('dict_1:', dict_1)
print('dict_3:', dict_3)

输出结果为:

dict_1: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 90, 'shuxue': 100}}

dict_2: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 90, 'shuxue': 100}}

-------------------------modify 90->98--------------------------

dict_1: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 98, 'shuxue': 100}}

dict_2: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 98, 'shuxue': 100}}

---------------------------deep copy----------------------------

dict_1: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 98, 'shuxue': 100}}

dict_3: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 98, 'shuxue': 100}}

-------------------------modify 98->99--------------------------

dict_1: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 99, 'shuxue': 100}}

dict_3: {'name': 'xiaowang', 'age': 20, 'score': {'yuwen': 98, 'shuxue': 100}}

 

所谓浅复制,其实是复制了内存的地址,并没有拷贝内存里面存的数据。

而深复制,则是重新分配了一块内存,并把数据拷贝进去。

所以,我们通过上面的实例可以看到,在浅复制的情况下,我们改变dict_1的值,dict_2依然会跟着变化,说明他们指向了同一块内存空间。而深复制的情况下,则互不影响,说明他们指向的是不同的内存空间。

通过下面的图,更加容易理解:

 

大家可以思考一下,为什么key为‘name’和‘age’的值不受浅复制的影响呢?

 

Set(集合)

在python中,集合是一个无序的不可重复的元素组合,它是不是和前面介绍的字典的key值很像呢?集合的语法如下:

{item1, item2, item3,…} 或者 set(iterable)

集合中的元素必须保证唯一,不可重复。

对于空集合,必须使用set()来创建,而不是使用{},因为这对应的是一个空字典。

Set的参数,是一个可迭代对象,后续我们在迭代器章节会详细介绍,目前我们学习到的序列类型结构,如字符串、元组、列表,都是可迭代的。参数中不能包含重复元素,否则自动覆盖。比如:


# file: ./5/5_9.py# 集合 Set
set_1 = set('hello')
print(set_1)

输出结果为:

{'l', 'e', 'o', 'h'}

 

我们可以看到,它的输出是无序的,并且重复的元素‘l’算作一个元素,是不可重复的。

集合的这种特性很适合用来对字典的key赋值:

dict_1 = {}.fromkeys(set_1)  # 批量根据key值初始化一个字典print(dict_1)

输出结果为:

{'h': None, 'l': None, 'e': None, 'o': None}

 

可以把集合理解为没有value只有key的字典。

 

集合中的元素必须是可hash的,也就是说元素是不可变的,这一点也和字典的key一样。比如列表就不能作为集合中的元素。

 

集合分为可变集合和不可变集合,使用frozenset()创建的是不可变集合,其它都是可变集合。不可变集合不支持增加、删除等操作。

 

下面通过实例来熟悉集合的一些操作:


# file: ./5/5_9.py# 集合 Set
set_1 = set('hello')
print(set_1)
print(len(set_1))dict_1 = {}.fromkeys(set_1)  # 批量根据key值初始化一个字典
print(dict_1)set_2 = frozenset('hello')  # 不可变集合
print(set_2)# 新增元素
set_1.add('t')
print(set_1)
set_1.update('k', 'p')  # 批量添加多个
print(set_1)# 删除元素
set_1.remove('t')
print(set_1)# 判断元素是否存在
print('t' in set_1)
print('t' not in set_1)# 清空元素
set_1.clear()
print(set_1)# 集合操作
set_3 = set('hello')
set_4 = set('world')print(set_3 - set_4)  # 补集
print(set_3 | set_4)  # 并集
print(set_3 & set_4)  # 交集
print(set_3 ^ set_4)  # 对称补集, 等同于 (set_3 - set_4) | (set_4 - set_3)set_5 = {1, 2}
set_6 = {1, 2, 3}
print(set_5 < set_6)  # 子集判断
print(set_5 > set_6)  # 超集判断

集合提供了类似数学里面集合概念的一些操作,比如并集、交集、子集、超集等,这在某些特殊场景下使用起来会非常方便。

 

 

可变数据类型和不可变数据类型

 

前面我们的学习中其实已经涉及到可变数据类型和不可变数据类型的概念了,这一节我们总结一下。

python的数据类型分为mutable(可变) 和 immutable (不可变):

  1. mutable包括list、dictionary、set
  2. immutable包括 number、string、bytes、tuple、frozenset

 

这里的可变与不可变,指的是该对象对应内存中的那块数据(value)是否允许改变。

如果是不可变类型数据,系统会重新分配一个对象,并将该对象的引用(可以理解为内存地址\指针)重新赋给变量。而可变类型则可以直接修改,不会生成新的对象。

 

在函数传参时,两者也存在差别。如果入参是不可变类型,那么是传值方式,如果入参是可变类型,那么传入的是对象的引用。这里我们要使用到函数的概念,因为还没有讲函数,所以大家先通过下面的一个实例记住这个知识点,后面学习函数的时候我们会再次提及。

#  author: Tiger,    wx ID:tiger-python# file: ./5/5_16.py# 可变数据类型和不可变数据类型
# 函数入参区别
def incr_num(x):x = x + 1def pop_list(list_1=[]):list_1.pop()test_x = 100
test_list = [100, 200, 300]incr_num(test_x)  # 不可变类型,传的是值
pop_list(test_list)  # 可变类型,传的是引用(地址)print(test_x)
print(test_list)# 不可变类型,需要return一个新的对象
def incr_num_2(x):y = x + 1return ytest_y = incr_num_2(test_x)
print(test_y)

通过上面实例可以看出,对于函数入参是可变类型的情况,它传递的是变量的值-值传递,函数里面处理的变量已经是指向了一个新的对象空间,所以在函数里面对它进行改变不会影响函数外面的变量。值传递的方式,需要return来返回结果。

而对于函数入参是不可变类型的情况,它传递的是变量指向对象空间的地址。函数里面对这个地址进行操作,同样会影响外部的变量。这种方式,不需要return结果。

 

动态类型和静态类型

编程语言从代码到能够运行通常需要经过编译和运行两个阶段,Python虽然是解释性语言,也不例外。源码.py通过编译,生成字节码文件.pyc。.pyc是一系列指令,这些指令通过python虚拟机PVM来执行。

 

我们根据检查变量数据类型的时机,将编程语言分为动态类型语言静态类型语言

静态类型:在编译阶段检查变量的数据类型,比如C、Java等。对于这种类型的语言,我们需要在代码中定义变量的数据类型,不管是显式的声明还是隐式的定义。静态类型语言的变量,一旦定义了数据类型,在运行时是不能动态改变的。比如C语言,它的典型用法如下:

void main(){int score1 = 0;  // 变量score1在使用之前需要声明为int类型,否则编译报错int score2 = 50;score1 = score2 + 10;// ......}

动态类型:在运行阶段才检查变量的数据类型。Python就是一种动态类型语言,它的变量不需要声明数据类型,只有在运行时才动态确定其类型。通过上一节的几个小实验我们其实可以看出来,python的变量本质上是一个内存地址,本身没有类型,它的数据类型由其指向的对象来决定。比如下面的例子,在python中是可以正常运行的:

# 此时,tmp是一个整数类型
tmp = 100
print(type(tmp))# 此时,tmp是一个字符串类型,类型可以动态改变
tmp = "hello, world!"
print(type(tmp))

它的输出是:

<class 'int'>

<class 'str'>

 

这种动态类型的特性,让python使用起来会更加简单,代码会更加简洁。但是它也会带来一些负面影响,比如无法在编译阶段发现问题,同时动态类型会带来运行时的一部分性能损耗。两者各有利弊。我们在使用python编程时,也建议随时搞清楚变量对应的数据类型,这样可以规避一些隐藏的问题。

 

数据类型转换

数据类型转换,指的是通过某种方法,将一个数据由原来的类型转换为另外一个类型。比如,我们将字符串“123”转换为数字123,这就是一种数据类型的转换。

Python支持各种标准数据类型之间的转换,但并不是任意数据都可以转换的,所有的转换要符合“常理”,逻辑上应该是成立的。比如,你不应该试图将一个complex类型转换为int,因为python也不知该怎么转换。

 

数据类型转换支持情况汇总表

下面我整理了python3数据类型之间转换的支持情况(这应该是最全的了):

 

Int

Float

Bool

Complex

String

Bytes

List

Tuple

Set

Dict

Int

-

Y

Y

N

Y

Y

N

N

N

N

Float

Y

-

Y

N

Y

Y

N

N

N

N

Bool

Y

Y

-

Y

Y

Y

Y

Y

Y

Y

Complex

Y

Y

Y

-

Y

N

N

N

N

N

String

Y

Y

Y

Y

-

Y

Y

Y

Y

Y

Bytes(只考虑直接转换)

Y

N

Y

N

Y

-

Y

Y

Y

N

List

N

N

N

N

Y

Y

-

Y

Y

Y

Tuple

N

N

N

N

Y

Y

Y

-

Y

Y

Set

N

N

N

N

Y

Y

Y

Y

-

Y

Dict

N

N

N

N

Y

N

Y

Y

Y

-

下面列举了各种类型之间的转换及实例:

转换实例

  • 转换为int

print(int(1.2))  # float -> int
print(int('123'))  # string -> int
print(int(b'456'))  # bytes -> int
print('0x%x' % (int.from_bytes(b'456', byteorder='little', signed=True)))
print(int(True))  # bool -> int

 

  • 转换为float

print(float('1.2'))  # string->float
print(float(b'3.4'))  # bytes -> float
print(float(123))  # int->float
print(float(False))  # bool->float

 

  • 转换为bool

所有类型都可以转换为bool型

print(bool(1))  # int->bool
print(bool(0.0))  # float->bool
print(bool(0 + 0j))  # complex->bool
print(bool(''))  # string->bool, 空字符串为False,其它都是True
print(bool(b'hello'))  # bytes->bool, 空为False,其它都是True
print(bool.from_bytes(b'\x00', byteorder='little'))  # bytes->bool
print(bool([]))  # list->bool, 空为False,其它都是True
print(bool(()))  # tuple->bool, 空为False,其它都是True
print(bool({}))  # dict->bool, 空为False,其它都是True
print(bool(set()))  # set->bool, 空为False,其它都是True


  • 转换为complex

print(complex(100))  # int->complex
print(complex(1.2))  # float->complex
print(complex(True))  # bool->complex
print(complex('1.2+2.3j'))  # string->complex

 

  • 转换为string

所有基本类型都可以转换为string

print(b'hello'.decode('utf-8'))  # bytes->string
print(str(1))  # int->string
print(str(1.2))  # float->string
print(str(True))  # bool->string
print(str(1.2 + 2.3j))  # complex->string其它都是True
print(str(['hello', 100]))  # list->string
print(str(('hello', 100)))  # tuple->string
print(str({'name': 'xiaowang', 'age': 20}))  # dict->string
print(str({'name', 'age'}))  # set->string

 

  • 转换为bytes

因为所有类型都可以转换为string,而string可以转换为bytes,所以所有类型都可以间接转换为bytes。
下面我们只讨论直接转换为bytes的类型

print('bytes'.center(30, '*'))
print(b'\x64')  # int转bytes
print(int.to_bytes(100, byteorder='big', signed=True, length=2))  # int转bytes
print(bool.to_bytes(True, byteorder='big', signed=True, length=2))  # bool转bytes
print('hello'.encode(encoding='utf-8'))  # string转bytes
print(bytes([1, 200, 80, 50]))  # list转bytes
print(bytes((1, 200, 80, 50)))  # tuple转bytes
print(bytes({1, 200, 80, 50}))  # set转bytes

 

  • 转换为list

print(list("hello"))  # string->list
print(list(b'hello'))  # bytes->list
print(list((100, 200, 300)))  # tuple->list
print(list({'name', 'age'}))  # set->list
print(list({'name': 'xiaowang', 'age': 20}))  # dict->list, 只取key值

 

  • 转换为tuple

print(tuple("hello"))  # string->tuple
print(tuple(b"hello"))  # bytes->tuple
print(tuple([100, 200, 300]))  # list->tuple
print(tuple({'name', 'age'}))  # set->tuple
print(tuple({'name': 'xiaowang', 'age': 20}))  # dict->tuple, 只取key值

 

  • 转换为set

print(set("hello"))  # string->set
print(set(b"hello"))  # bytes->set
print(set([100, 200, 300]))  # list->set
# print(set([100, 200, [300, 400]]))  # list->set, list中包含可变数据类型,报异常
print(set(('name', 'age')))  # tuple->set
# print(set(('name', 'age', [])))  # tuple->set,包含可变数据类型,报异常
print(set({'name': 'xiaowang', 'age': 20}))  # dict->set, 只取key值

 

  • 转换为dict

转换为dict的方法略微复杂一些

1、string->dict

方式一、使用json转换,字符串格式需要严格按照json格式来

user_str = '{"name": "xiaowang", "city": "Chengdu", "age": 28}'
import json
print(json.loads(user_str))  

方式二、使用eval函数转换,eval有安全隐患,不建议使用

print(eval(user_str))  

方式三、 使用ast.literal_eval

import ast
print(ast.literal_eval(user_str))  

 

2、list->dict

 

方式一、需要用到zip

user_keys = ['name', 'city', 'age']
user_values = ['xiaowang', 'Chengdu', 28]
print(dict(zip(user_keys, user_values)))  

 

方式二、二维列表

user_info = [
["name", "xiaowang"],
["city", "Chengdu"],
["age", 28]
]
print(dict(user_info))  


set->dict tuple->dict的方式和list->dict一样


 

关于这个系列

《最值得收藏的python3语法汇总》,是我为了准备公众号“跟哥一起学python”上面视频教程而写的课件。整个课件将近200页,10w字,几乎囊括了python3所有的语法知识点。

你可以关注这个公众号“跟哥一起学python”,获取对应的视频和实例源码。

这是我和几位老程序员一起维护的个人公众号,全是原创性的干货编程类技术文章,欢迎关注。

 

该系列其它文章

《最值得收藏的python3语法汇总》之数据类型转换

《最值得收藏的python3语法汇总》之函数机制

《最值得收藏的python3语法汇总》之运算符

《最值得收藏的python3语法汇总》之控制语句

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. c语言入门到c++使用高手:深入学习C++之基本语言(四)

    第二章 基本语言 第四节 范围for、new内存动态分配、nullptr 1. 范围for语句用于遍历一个序列#include <iostream>using namespace std;int main() {int v[]{12, 13, 15, 17, 88};// 数组v中每个元素,依次放入x中并打印x的值,把v中每个元素的值拷贝到x中,打印x的值for (a…...

    2024/4/24 7:40:55
  2. TX2 使用ros serial控制出现的问题

    在调试过程中,使用ttyTHS2进行串口通信,串口采用ros自带的serial来操作,ttyTHS2默认是TTL电平,实际使用了TTL->232模块。第一次使用正常,当关闭程序之后,重新打开程序,TTL->232模块的电源指示灯由亮变暗,但是程序显示串口初始化正常。排除软件的问题,电源指示灯…...

    2024/4/24 7:40:57
  3. Netty 一个简单的测试

    Netty 一个简单的测试1. 导包2. 测试类2. 初始化器3. 自定义助手类4. 浏览效果 1. 导包<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.50.Final</version></dependency><depend…...

    2024/4/24 7:40:56
  4. 【LeetCode-92】92.翻转链表II(反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。)

    翻转链表II 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明: 1 ≤ m ≤ n ≤ 链表长度。/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/ class Solution {public Li…...

    2024/4/24 7:40:52
  5. SQL Server 跨服务器查询数据

    假设有两台服务器,服务器1为192.168.0.123,服务器2为192.168.0.234。场景为想在服务器1上访问服务器2内test数据库的order表,语句如下:SELECT * FROM OPENROWSET(SQLOLEDB,192.168.0.234;用户名;密码,test.dbo.order)有问题欢迎交流...

    2024/4/24 7:40:51
  6. Qt源码分享(四)--自定义标签,源码分享

    Qt源码分享(四)–自定义标签,源码分享 由于最近的疫情的影响,导致公司走了一部分人。又是项目的重新启动,导致我没有时间写文章了。分享一些自定义控件,是从公司的项目中抠出来的。关注微信号:cpp手艺人,获取源码 好,废话不说,先看看效果怎么样。 1.自绘制图片 2.大小…...

    2024/4/24 7:40:53
  7. 阿里云服务器和腾讯云服务器那家好?(数据对比)

    服务器具有维护成本低,安全稳定,高可扩展性和 7 X 24 小时的售后支持的优势,因此云服务器成为中小企业建站的首要选择。国内的云服务器竞争也进入了跑马圈地的时代,以阿里云、腾讯云、百度云三大BAT为首,不断推出优惠活动,争取更多的用户体量;以华为云、天翼云、西部数据…...

    2024/4/24 7:40:56
  8. 在linux服务器上部署springboot项目,并让他持续在后台运行

    我们知道在运行springboot 项目只需要java -jar + 项目的war包(jar包)名。 但是只要终端已停止那么服务就会被关闭,也就无法访问到我们的项目了。所以我们可以使用守护进程的方式来让服务运行在后台。 1.编写脚本如下:这里的&不能省略 ,表示守护进程的意思,运行在后台…...

    2024/4/16 19:06:12
  9. Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.properties.Configurati

    前言 在nacos集群搭建完以后,本地服务启动注册到集群上面,其实没有怎么配置,就是一个空的jar包项目,然后报错: "C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:60695,suspend=y,server=n -XX:Tiered…...

    2024/4/20 2:19:06
  10. Java 生成二维码以Base64串存DB,读取网页显示

    QrcodeUtils.java 源码:package com.pay.utils;import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.common.BitMatrix; import sun.misc.BASE64Encoder;import javax.imag…...

    2024/4/18 6:57:07
  11. 非计算机系学生如何快速掌握计算机技术?

    今天的推文内容来自于公众号后台一位小伙伴的留言。这位小伙伴本科不是计算机专业,但未来想要从事计算机行业,对于具体要怎么去做产生了疑问,希望可以得到一些建议。对此,小茴香整理了相关的经验,就非计算计专业的小伙伴,如果想要跨行从事计算机技术,该怎么去思考和规划…...

    2024/4/16 19:06:36
  12. 动态域名解析NAT版结合绿盾加密解密软件使用方法

    今天遇到的客户需求是这样的,客户使用了一套绿盾加密解密系统,这套系统分服务器端和客户端,客户端如果想打开文件需要得到服务器端的授权,同时客户有异地办公的需求,另外服务器没有公网IP,下面开始实施。一:部署绿盾加密解密系统服务器端(这个我完全不懂,直接略过了)…...

    2024/4/16 19:06:18
  13. (免安装vim)修改docker下mysql配置文件

    使用docker安装完mysql之后,总会有一些需要修改mysql配置的时候。修改配置文件就需要用到了vi或者vim命令来对my.cnf文件进行修改了。如果是在有网络的环境下安装vim插件的话那就简单方便的了,教程也是网上一大推。但是在无网络的环境下想安装vim时,那就非常的麻烦,坑爹了,…...

    2024/4/16 19:06:30
  14. Substrings Sort CodeForces - 988B(sort()+s.find()函数应用)

    水题,记录一下两个函数的使用。AC代码:#include <iostream> #include <string> #include <algorithm> using namespace std; string s[105]; bool cmp(string a,string b){if(a.size()!=b.size())return a.size()<b.size();else return a<b; } int m…...

    2024/4/16 19:06:18
  15. STM8框架使用指引

    一、概述编写该框架是为了避免一个很尴尬的情况:一个公司几位工程师,每位工程师看似合作,但提交的代码却是框架各异、风格迥然,你看我的代码别扭,我看你的代码费神……这些都增加了沟通成本、出错成本,不利于项目维护和传承。新接手的工程师看到一堆充满异域风情的代码时…...

    2024/4/16 19:06:30
  16. 小程序实现全选,包括计算价格

    效果图1、html<view class="content"><checkbox-group @change="checkboxChange" class="wrapper"><view class="cart-item" v-for="(item,index) in shopcartList" :key="index"><label c…...

    2024/4/27 5:58:59
  17. 二、[动图] 选择排序 其它语言[ python、java、go、php、c++、c等 ] 数据结构与算法

    1. 选择排序定义 选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。 2. 算法步骤 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。 再从剩余…...

    2024/4/24 7:40:47
  18. 下拉菜单效果和tab选项卡切换

    //下拉菜单效果和tab选项卡切换。<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><me…...

    2024/4/24 7:40:53
  19. CentOS管理用户登录权限及禁止用户登录

    LINUX管理用户登录权限,禁止用户登录1、禁止个别用户登录。比如禁止 user 用户登录。passwd -l user这就话的意思是锁定user用户,这样该用户就不能登录了。passwd -u user对锁定的用户user进行解锁,用户可登录了。2、通过修改 /etc/passwd 文件中用户登录的shellvim /et…...

    2024/4/24 7:40:52
  20. SQL Sever学习笔记1——SQL

    SQL1.SQL语句及种类2.SQL的基本书写规则3.表的创建与操作(插入、更新、修改、删除) SQL是为操作数据库而开发的语言 1.SQL语句及种类 SQL语句可以分为以下三类DDL(Data Definition Language,数据定义语言)用来创建或者删除存储数据用的数据库以及数据库中的表等对象。DDL …...

    2024/4/24 7:40:44

最新文章

  1. 前端CSS基础12(布局)

    前端CSS基础12&#xff08;布局&#xff09; 版心常用布局名词 版心 在网页设计中&#xff0c;“版心”&#xff08;也称为"内容区"&#xff09;是指网页上主要内容显示的区域&#xff0c;通常是页面中间部分。版心的主要功能是容纳网页的核心内容&#xff0c;例如文…...

    2024/4/27 17:57:01
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. pyside6的QSpinBox自定义特性初步研究(二)

    当前的需求是&#xff0c;蓝色背景的画面&#xff0c;需要一个相对应色系的QSpinBox部件。已有的部件风格是这样的&#xff0c;需要新的部件与之般配。 首先新建一个QDoubleSpinBox&#xff0c;并定义其背景色和边框&#xff1a; QDoubleSpinBox { color: white; border:1px…...

    2024/4/19 15:59:18
  4. ssm框架中各层级介绍

    1、Spring&#xff08;业务逻辑层&#xff09;&#xff1a; Spring框架提供了依赖注入&#xff08;DI&#xff09;和面向切面编程&#xff08;AOP&#xff09;等功能&#xff0c;可以帮助管理Java应用程序中的对象依赖关系和提供横切关注点的支持。 在SSM框架中&#xff0c;S…...

    2024/4/27 13:24:33
  5. [实战经验]Mybatis的mapper.xml参数#{para}与#{para, jdbcType=BIGINT}有什么区别?

    在MyBatis框架中&#xff0c;传入参数使用#{para}和#{para, jdbcTypeBIGINT}的有什么区别呢&#xff1f; #{para}&#xff1a;这种写法表示使用MyBatis自动推断参数类型&#xff0c;并根据参数的Java类型自动匹配数据库对应的类型。例如&#xff0c;如果参数para的Java类型是Lo…...

    2024/4/26 8:43:28
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/26 18:09:39
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/26 20:12:18
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/26 23:05:52
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/27 4:00:35
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/25 18:39:22
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/26 21:56:58
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/27 9:01:45
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/26 16:00:35
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/25 18:39:16
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/26 22:01:59
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/25 2:10:52
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/25 18:39:00
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/26 19:46:12
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/27 11:43:08
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/27 8:32:30
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57