Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。
Python 访问子字符串,可以使用方括号来截取字符串,如下实例:
var1 = 'Hello World!'
var2 = "Sunchengquan"
print ("var1[0]: ", var1[0])
print ("var2[1:5]: ", var2[3:8])
var1[0]: H
var2[1:5]: cheng
var1 = 'Hello World!'
print ("已更新字符串 : ", var1[:6] + 'Sunchengquan!')
已更新字符串 : Hello Sunchengquan!
转义字符就是反斜杠’’,对于想要将其作为一个字符处理的单引号或者双引号而言,前面只要加上转义字符就可以了。例如对于字符串Let’s go!,我们就可以这样写’Let\‘s go!’。另外,我们也可以使用"Let’s go!"来表示。
print('Let\'s go!')
print("Let's go!")
Let's go!
Let's go!
转义字符 | 描述 |
---|---|
\(在行尾时) | 续行符 |
\ | 反斜杠符号 |
\’ | 单引号 |
\" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\e | 转义 |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制数,yy代表的字符,例如:\o12代表换行 |
\xyy | 十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other | 其它的字符以普通格式输出 |
下表实例变量a值为字符串 “Hello”,b变量值为 “Python”:
操作符 | 描述 | 实例 |
---|---|---|
+ | 字符串连接 | a + b 输出结果: HelloPython |
* | 重复输出字符串 | a*2 输出结果:HelloHello |
[] | 通过索引获取字符串中字符 | a[1] 输出结果 e |
[ : ] | 截取字符串中的一部分,遵循左闭右开原则,str[0,2] 是不包含第 3 个字符的。 | a[1:4] 输出结果 ell |
in | 成员运算符 - 如果字符串中包含给定的字符返回 True | ‘H’ in a 输出结果 True |
not in | 成员运算符 - 如果字符串中不包含给定的字符返回 True | ‘M’ not in a 输出结果 True |
r/R | 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 | print( r’\n’ )print( R’\n’ ) |
% | 格式字符串 | 请看下一节内容 |
a = "Hello"
b = "Sunchengquan"
print("a + b 输出结果:", a + b)
print("a * 2 输出结果:", a * 2)
print("a[1] 输出结果:", a[1])
print("a[1:4] 输出结果:", a[1:4])
if "H" in a :
print("H 在变量 a 中")
else :
print("H 不在变量 a 中")
if "M" not in a :
print("M 不在变量 a 中")
else :
print("M 在变量 a 中")
print(r'\n')
print(R'\n')
a + b 输出结果: HelloSunchengquan
a * 2 输出结果: HelloHello
a[1] 输出结果: e
a[1:4] 输出结果: ell
H 在变量 a 中
M 不在变量 a 中
\n
\n
格式化字符串的函数 str.format(),它增强了字符串格式化的功能。
基本语法是通过 {} 和 : 来代替以前的 % 。
format 函数可以接受不限个参数,位置可以不按顺序
print("不设置指定位置,按默认顺序")
print("{} {}".format("hello", "world") )
print("设置指定位置")
print("{1} {0} {1}".format("hello", "sun") )
'{0:.1f}{1}'.format(27.68,'GB')
不设置指定位置,按默认顺序
hello world
设置指定位置
sun hello sun
'27.7GB'
也可以设置参数:
'{0} love {A}.{B}'.format('I',A='SUN',B='CHENGQUAN')
'I love SUN.CHENGQUAN'
数字格式化
print("{:.2f}".format(3.1415926))
3.14
使用大括号 {} 来转义大括号,如下实例:
print ("{} 对应的位置是 {
{0}}".format("sun"))
sun 对应的位置是 {0}
name = "my \tname is {name} and i am {year} old"
print(name.format_map( {
'name':'alex','year':12} ))
my name is alex and i am 12 old
数字 | 格式 | 输出 | 描述 |
---|---|---|---|
3.1415926 | {:.2f} | 3.14 | 保留小数点后两位 |
3.1415926 | {:+.2f} | +3.14 | 带符号保留小数点后两位 |
-1 | {:+.2f} | -1.00 | 带符号保留小数点后两位 |
2.71828 | {:.0f} | 3 | 不带小数 |
5 | {:0>2d} | 05 | 数字补零 (填充左边, 宽度为2) |
5 | {:x<4d} | 5xxx | 数字补x (填充右边, 宽度为4) |
10 | {:x<4d} | 10xx | 数字补x (填充右边, 宽度为4) |
1000000 | {:,} | 1,000,000 | 以逗号分隔的数字格式 |
0.25 | {:.2%} | 25.00% | 百分比格式 |
1000000000 | {:.2e} | 1.00e+09 | 指数记法 |
13 | {:10d} | 13 | 右对齐 (默认, 宽度为10) |
13 | {:<10d} | 13 | 左对齐 (宽度为10) |
13 | {:^10d} | 13 | 中间对齐 (宽度为10) |
11 | ‘{:b}’.format(11) | 1011 | 二进制 |
11 | ‘{?}’.format(11) | 13 | 八进制 |
11 | ‘{:d}’.format(11) | 11 | 十进制 |
11 | ‘{:x}’.format(11) | b | 十六进制 |
11 | ‘{:#x}’.format(11) | 0xb | 十六进制 |
字符串格式化操作符(%)
在 Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法。
print('my name is %s' % 'sunchengquan')
print('%d + %d = %d' % (2,3,2+3))
# 定义字符串变量 name,输出 我的名字叫 小明,请多多关照!
name = "大小明"
print("我的名字叫 %s,请多多关照!" % name)
# 定义整数变量 student_no,输出 我的学号是 000001
student_no = 10012
print("我的学号是 %06d" % student_no)
# 定义小数 price、weight、money,
# 输出 苹果单价 9.00 元/斤,购买了 5.00 斤,需要支付 45.00 元
price = 8.5
weight = 7.5
money = price * weight
print("苹果单价 %.2f 元/斤,购买了 %.3f 斤,需要支付 %.4f 元" % (price, weight, money))
# 定义一个小数 scale,输出 数据比例是 10.00%
# %% 输出%
scale = 0.8
print("数据比例是 %.2f%%" % (scale * 100))
my name is sunchengquan
2 + 3 = 5
我的名字叫 大小明,请多多关照!
我的学号是 010012
苹果单价 8.50 元/斤,购买了 7.500 斤,需要支付 63.7500 元
数据比例是 80.00%
字符串格式化符号
符 号 | 描述 |
---|---|
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
格式化操作符辅助指令
符号 | 功能 |
---|---|
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
在正数前面显示空格 | |
# | 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’) |
0 | 显示的数字前面填充’0’而不是默认的空格 |
% | ‘%%‘输出一个单一的’%’ |
(var) | 映射变量(字典参数) |
m.n. | m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) |
三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符
print( '''前人不是说:没有痛苦,叫什么诗人?\t——我记得这是莱蒙托夫的诗句。
连这话他都知道,事情看来很有点不妙了,\n别人的痛苦才是你艺术的源泉;而你去受苦,只会成为别人的艺术源泉。''')
前人不是说:没有痛苦,叫什么诗人? ——我记得这是莱蒙托夫的诗句。
连这话他都知道,事情看来很有点不妙了,
别人的痛苦才是你艺术的源泉;而你去受苦,只会成为别人的艺术源泉。
方法 | 描述 |
---|---|
string.capitalize() | 把字符串的第一个字符大写 |
string.casefold() | 包括英文和其它一些语言里面大写字母转换为小写 |
string.center(width) | 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串 |
string.count(str, beg=0, end=len(string)) | 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 |
bytes.decode(encoding=‘UTF-8’, errors=‘strict’) | 以 encoding 指定的编码格式解码 string,如果出错默认报一个 ValueError 的 异 常 , 除非 errors 指 定 的 是 ‘ignore’ 或 者’replace’ |
string.encode(encoding=‘UTF-8’, errors=‘strict’) | 以 encoding 指定的编码格式编码 string,如果出错默认报一个ValueError 的异常,除非 errors 指定的是’ignore’或者’replace’ |
string.endswith(obj, beg=0, end=len(string)) | 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. |
string.expandtabs(tabsize=8) | 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 |
string.find(str, beg=0, end=len(string)) | 检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1 |
string.format() | 格式化字符串 |
string.index(str, beg=0, end=len(string)) | 跟find()方法一样,只不过如果str不在 string中会报一个异常 |
string.isalnum() | 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False |
string.isalpha() | 如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False |
string.isdecimal() | 如果 string 只包含十进制数字则返回 True 否则返回 False. |
string.isdigit() | 如果 string 只包含数字则返回 True 否则返回 False. |
string.isidentifier() | 判读是不是一个合法的标识符(是不是合法的变量名) |
string.islower() | 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
string.isnumeric() | 如果 string 中只包含数字字符,则返回 True,否则返回 False |
string.isspace() | 如果 string 中只包含空格,则返回 True,否则返回 False. |
string.istitle() | 如果 string 是标题化的(见 title())则返回 True,否则返回 False |
string.isupper() | 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
string.join(seq) | 以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
string.ljust(width) | 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串 |
string.lower() | 转换 string 中所有大写字符为小写. |
string.lstrip() | 截掉 string 左边的空格 |
string.maketrans(intab, outtab]) | maketrans() 方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标 |
max(str) | 返回字符串 str 中最大的字母 |
min(str) | 返回字符串 str 中最小的字母 |
string.partition(str) | 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把 字 符 串 string 分 成 一 个 3 元 素 的 元 组 (string_pre_str,str,string_post_str),如果 string 中不包含str 则 string_pre_str == string. |
string.replace(str1, str2, num=string.count(str1)) | 把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次 |
string.rfind(str, beg=0,end=len(string)) | 类似于 find()函数,不过是从右边开始查找. |
string.rindex( str, beg=0,end=len(string)) | 类似于 index(),不过是从右边开始. |
string.rjust(width) | 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串 |
string.rpartition(str) | 类似于 partition()函数,不过是从右边开始查找 |
string.rstrip() | 删除 string 字符串末尾的空格. |
string.split(str="", num=string.count(str)) | 以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串 |
string.splitlines([keepends]) | 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符 |
string.startswith(obj, beg=0,end=len(string)) | 检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查 |
string.strip([obj]) | 在 string 上执行 lstrip()和 rstrip() |
string.swapcase() | 翻转 string 中的大小写 |
string.title() | 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) |
string.translate(str, del="") | 根据 str 给出的表(包含 256 个字符)转换 string 的字符,要过滤掉的字符放到 del 参数中 |
string.upper() | 转换 string 中的小写字母为大写 |
string.zfill(width) | 返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0 |
name = "my \tname is {name} and i am {year} old"
#字符串的一个字母大写
print(name.capitalize())
My name is {name} and i am {year} old
'''lower() 只对 ASCII 也就是 'A-Z'有效,
但是其它一些语言里面存在小写的情况就没办法了。
文档里面举得例子是德语中'ß'的小写是'ss':'''
str1 = 'A'
print(str1.casefold())
print(str1.lower())
str2 = 'ß'
print(str2.casefold())
print(str2.lower())
a
a
ss
ß
#总打印50字符,name居中,其余用"-"补齐
print(name.center(50,"-"))
------my name is {name} and i am {year} old------
print(name.count("a"))
5
py3字符串也有两种数据类型:str和bytes; str类型存unicode数据,bytes类型存bytes数据,与py2比只是换了一下名字而已,后面会有深入讲解。
以Unicode表示的str通过encode()方法可以编码为指定的bytes
如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法
str = "孙成全"
str_utf8 = str.encode("UTF-8")
str_gbk = str.encode("GBK")
print(type(str),str)
print("UTF-8 编码:", str_utf8)
print("GBK 编码:", str_gbk)
print("UTF-8 解码:", str_utf8.decode('UTF-8','strict'))
print("GBK 解码:", str_gbk.decode('GBK','strict'))
孙成全
UTF-8 编码: b'\xe5\xad\x99\xe6\x88\x90\xe5\x85\xa8'
GBK 编码: b'\xcb\xef\xb3\xc9\xc8\xab'
UTF-8 解码: 孙成全
GBK 解码: 孙成全
#判断字符串以什么结尾
print(name.endswith("ex"))
False
#自定义tab与空格的关系
str = name
print ("原始字符串: " + str)
print ("替换 \\t 符号: " + str.expandtabs())
print ("使用16个空格替换 \\t 符号: " + str.expandtabs(16))
原始字符串: my name is {name} and i am {year} old
替换 \t 符号: my name is {name} and i am {year} old
使用16个空格替换 \t 符号: my name is {name} and i am {year} old
#字符串切片,从name的位置开始
print(name[name.find("name"):])
str1 = "sunchengquan example....wow!!!"
str2 = "exam";
print (str1.find(str2)) ## 从下标0开始,查找在字符串里第一个出现的子串
print (str1.find(str2, 5)) ## # 从下标5开始,查找在字符串里第一个出现的子串
print (str1.find(str2, 15)) # 从下标15开始,查找在字符串里第一个出现的子串:查找不到返回-1
name is {name} and i am {year} old
13
13
-1
str1 = "sunchengquan example....wow!!!"
str2 = "exam";
print (str1.index(str2))
print (str1.index(str2, 5))
print (str1.index(str2, 15))
13
13
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
4 print (str1.index(str2))
5 print (str1.index(str2, 5))
----> 6 print (str1.index(str2, 15))
ValueError: substring not found
str = "python2018" # 字符串没有空格
print (str.isalnum())
str = "sunchengquan ....wow!!!"
print (str.isalnum())
True
False
#判断字符串是否由英文字母组成
print('abA'.isalpha())
print('ab A'.isalpha())
True
False
#是否是十进制
print('0xa'.isdecimal())
print('0o23'.isdecimal())
print('23'.isdecimal())
False
False
True
str = "123456";
print (str.isdigit())
str = "sunchengquan ....wow!!!!!!"
print (str.isdigit())
True
False
#判读是不是一个合法的标识符(是不是合法的变量名)
print('a 1A'.isidentifier())
False
str = "SUNchengquan ....wow!!!!!!"
print (str.islower())
str = "sunchengquan ....wow!!!!!!"
print (str.islower())
False
True
str = "runoob2016"
print (str.isnumeric())
str = "23443434"
print (str.isnumeric())
False
True
%%python2
# -*- coding:utf-8 -*-
#isnumeric() 方法检测字符串是否只由数字组成。这种方法是只针对unicode对象
str = u"runoob2016"
print (str.isnumeric())
str = u"23443434"
print (str.isnumeric())
False
True
str = " "
print (str.isspace())
str = "sunchengquan ....wow!!!"
print (str.isspace())
True
False
#是否标题(单词首字母大写)
print('My Name is '.istitle())
str = "This Is String Example...Wow!!!"
print (str.istitle())
str = "This is string example....wow!!!"
print (str.istitle())
False
True
False
str = "THIS IS STRING EXAMPLE....wOW!!!"
print (str.isupper())
print (str.upper().isupper())
str = "THIS is string example....wow!!!"
print (str.isupper())
False
True
False
s1 = "-"
s2 = ""
s3 = "\t"
seq = ("r", "u", "n", "o", "o", "b")
seq1= 'rrrrrr'
print (s1.join( seq ))
print (s2.join( seq ))
print (s3.join( seq ))
print (s1.join( seq1 ))
r-u-n-o-o-b
runoob
r u n o o b
r-r-r-r-r-r
str.ljust(width[, fillchar])
str = "sunchengquan ....wow!!!"
print (str.ljust(50, '*'))
sunchengquan ....wow!!!***************************
str1 = "sunchengquan ....wow!!!"
print(str1.lower())
sunchengquan ....wow!!!
str.lstrip([chars])
str1 = "\n\tsunchengquan ....wow!!!"
print(str1)
print(str1.lstrip())
print(str1.lstrip("\n"))
str2 = "666666sunchengquan ....wow!!!666666"
print(str2.lstrip('6'))
sunchengquan ....wow!!!
sunchengquan ....wow!!!
sunchengquan ....wow!!!
sunchengquan ....wow!!!666666
intab = "aeiou"
outtab = "12345"
trantab = str.maketrans(intab, outtab)
str = "this is string example....wow!!!"
print (str.translate(trantab))
th3s 3s str3ng 2x1mpl2....w4w!!!
str = "sunchengquan"
print ("最大字符: " + max(str))
最大字符: u
str = "sunchengquan"
print ("最小字符: " + min(str))
最小字符: a
str = "www.runoob.com"
print(str.partition("."))
print(str.partition("#"))
print(str.partition("w"))
('www', '.', 'runoob.com')
('www.runoob.com', '', '')
('', 'w', 'ww.runoob.com')
s1 = "sunchengquan"
print ("旧名字:", s1)
print ("新名字:", s1.replace("sun", "SUN"))
s2 = "this is string example....wow!!!"
print (s2.replace("is", "was", 1))
print (s2.replace("is", "was", 2))
print (s2.replace("is", "was", 3))
#去除文本中的换行符
s3 = "\nsun\ncheng\nquan\n"
print ("原字符串", s3)
print ("使用strip", s3.strip())
print ("使用replace", s3.replace("\n",""))
旧名字: sunchengquan
新名字: SUNchengquan
thwas is string example....wow!!!
thwas was string example....wow!!!
thwas was string example....wow!!!
原字符串
sun
cheng
quan
使用strip sun
cheng
quan
使用replace sunchengquan
str1 = "this is really a string example....wow!!!"
str2 = "is"
print (str1.rfind(str2))
print (str1.rfind(str2, 0, 10))
print (str1.rfind(str2, 10, 0))
print (str1.find(str2))
print (str1.find(str2, 0, 10))
print (str1.find(str2, 10, 0))
5
5
-1
2
2
-1
str1 = "this is really a string example....wow!!!"
str2 = "is"
print (str1.rindex(str2))
print (str1.rindex(str2,10))
5
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
3
4 print (str1.rindex(str2))
----> 5 print (str1.rindex(str2,10))
ValueError: substring not found
str = "this is string example....wow!!!"
print (str.rjust(50, '*'))
******************this is string example....wow!!!
str = "www.runoob.com"
print(str.partition("."))
print(str.rpartition("."))
('www', '.', 'runoob.com')
('www.runoob', '.', 'com')
str1 = "sunchengquan ....wow!!!\t\t\n"
print(str1)
print(str1.rstrip(),str1.rstrip().count('\t'))
print(str1.rstrip("\n"),str1.rstrip("\n").count("\t"))
str2 = "666666sunchengquan ....wow!!!666666"
print(str2.rstrip('6'))
sunchengquan ....wow!!!
sunchengquan ....wow!!! 0
sunchengquan ....wow!!! 2
666666sunchengquan ....wow!!!
str = "this is string example....wow!!!"
print (str.split())
print (str.split('i',1))
print (str.split('i',2))
print (str.split('i'))
print (str.split('w'))
['this', 'is', 'string', 'example....wow!!!']
['th', 's is string example....wow!!!']
['th', 's ', 's string example....wow!!!']
['th', 's ', 's str', 'ng example....wow!!!']
['this is string example....', 'o', '!!!']
a = 'ab c\n\nde fg\rkl\r\n'.splitlines()
b = 'ab c\n\nde fg\rkl\r\n'.splitlines(True)
print(a)
print(b)
['ab c', '', 'de fg', 'kl']
['ab c\n', '\n', 'de fg\r', 'kl\r\n']
str = "this is string example....wow!!!"
print (str.startswith( 'this' ))
print (str.startswith( 'string', 8 ))
print (str.startswith( 'this', 2, 4 ))
True
True
False
str = "*****this is **string** example....wow!!!*****"
print (str.strip( '*' )) # 指定字符串 *
str = "123abcrunoob321"
print (str.strip( '12' )) # 字符序列为 12
str = "213abcrunoob312"
print (str.strip( '12' )) # 字符序列为 12
this is **string** example....wow!!!
3abcrunoob3
3abcrunoob3
str = "this is string example....wow!!!"
print (str.swapcase())
str = "This Is String Example....WOW!!!"
print (str.swapcase())
THIS IS STRING EXAMPLE....WOW!!!
tHIS iS sTRING eXAMPLE....wow!!!
txt = "hello b2b2b2 and 3g3g3g"
x = txt.title()
print(x)
Hello B2B2B2 And 3G3G3G
# 制作翻译表
bytes_tabtrans = bytes.maketrans(b'abcdefghijklmnopqrstuvwxyz', b'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
# 转换为大写,并删除字母o
print(b'runoob'.translate(bytes_tabtrans, b'o'))
b'RUNB'
str = "this is string example from runoob....wow!!!"
print ("str.upper() : ", str.upper())
str.upper() : THIS IS STRING EXAMPLE FROM RUNOOB....WOW!!!
str = "this is string example from runoob....wow!!!"
print ("str.zfill : ",str.zfill(40))
print ("str.zfill : ",str.zfill(50))
str.zfill : this is string example from runoob....wow!!!
str.zfill : 000000this is string example from runoob....wow!!!
因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。
ASCII是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 = 256-1,所以,ASCII码最多只能表示 255 个符号。
处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号
1995年的汉字扩展规范GBK1.0收录了21886个符号
2000年的 GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。
全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
每一个字符对应一个十六进制数字。计算机只懂二进制,因此,严格按照unicode的方式(UCS-2),应该这样存储:
str | unicode字符集 | 严格按照unicode的方式(UCS-2) |
---|---|---|
I | 0049 | 00000000 01001001 |
成 | 6210 | 01100010 00010000 |
如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
I | 01001001 | 00000000 01001001 | 01001001 |
成 | x | 01100010 00010000 | 11100110 10001000 10010000 |
一言以蔽之:Unicode是内存编码表示方案(是规范),而UTF是如何保存和传输Unicode的方案(是实现)这也是UTF与Unicode的区别。
encode是编码,即从unicode格式到二进制(bytes)的编码格式如utf-8、gb2312,ASCII等
decode是解码,即从二进制编码格式到unicode编码格式
python2的默认编码是ascii
%%bash
source activate python2.7
which python
source deactivate
/root/miniconda3/envs/python2.7/bin/python
%%writefile test1.py
#!/root/miniconda3/envs/python2.7/bin/python
print "你好,世界"
Overwriting test1.py
报错:ascii码无法表示中文
!chmod 755 test1.py
!./test1.py
File "./test1.py", line 3
SyntaxError: Non-ASCII character '\xe4' in file ./test1.py on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
改正:应该显示的告诉python解释器,用什么编码来执行源代码,即:
%%writefile test2.py
#!/root/miniconda3/envs/python2.7/bin/python
# -*- coding: utf-8 -*-
print "你好,世界"
Overwriting test2.py
!chmod 755 test2.py
!./test2.py
你好,世界
python2中字符串有两种表示形式,str和unicode。str类型存二进制编码格式(bytes)数据,Unicode类型存unicode数据
%%python2
# -*- coding: utf-8 -*-
s1='成'
print type(s1),s1 #
print repr(s1) #'\xe6\x88\x90'
s2=u'成'
print type(s2) #
print repr(s2)
import re
print re.search("\u(\w+)'$",str(repr(s2))).group(1)
print int(re.search("\u(\w+)'$",str(repr(s2))).group(1),16)
print bin(int(re.search("\u(\w+)'$",str(repr(s2))).group(1),16))
成
'\xe6\x88\x90'
u'\u6210'
6210
25104
0b110001000010000
%%python2
print bin(int('e6',16))
print bin(int('88',16))
print bin(int('90',16))
0b11100110
0b10001000
0b10010000
内置函数repr可以帮我们在这里显示存储内容。原来,str和unicode分别存的是字节数据和unicode数据;那么两种数据之间是什么关心呢?如何转换呢?这里就涉及到编码(encode)和解码(decode)了
%%writefile test3.py
#!/bin/python2
# -*- coding: utf-8 -*-
import sys
# reload(sys) #Python2.5 初始化后删除了 sys.setdefaultencoding 方法,我们需要重新载入
# sys.setdefaultencoding('utf-8')
print(sys.getdefaultencoding())
s1=u'成'
print repr(s1) #u'\u6210'
b=s1.encode('utf8')
print b
print type(b) #
print repr(b)
u=b.decode(encoding = 'utf-8')
print u
print type(u)
print repr(u)
Overwriting test3.py
!chmod 755 test3.py
!./test3.py
ascii
u'\u6210'
成
'\xe6\x88\x90'
成
u'\u6210'
%%writefile test4.py
#!/bin/python2
# -*- coding: utf-8 -*-
import sys
reload(sys) #Python2.5 初始化后删除了 sys.setdefaultencoding 方法,我们需要重新载入
sys.setdefaultencoding('utf-8')
print(sys.getdefaultencoding())
s = "孙成全"
u = u"孙成全"
#encode是编码,即从unicode格式到二进制的编码格式如utf-8、gb2312等
u_utf = u.encode("utf-8")
u_gb2312 = u.encode("gb2312")
#decode是解码,即从二进制编码格式str到unicode编码格式
u_gb2312_u = u_gb2312.decode('gb2312')
u_gb2312_u_utf8 = u_gb2312.decode('gb2312').encode("utf-8")
s_u = s.decode("utf-8")
s_u_gb2312 = s_u.encode("gb2312")
s_u_gb2312_u = s_u_gb2312.decode('gb2312')
gb2312_gbk_u =s_u_gb2312.decode("gbk")
gb2312_gbk = gb2312_gbk_u.encode("gbk")
gb2312_utf8 = gb2312_gbk_u.encode("utf-8")
print "s:",s
print "u",u
print "u_utf",u_utf
print 'u_gb2312', u_gb2312
print 'u_gb2312_u',u_gb2312_u
print 'u_gb2312_u_utf8',u_gb2312_u_utf8
print 's_u',s_u,type(s_u)
print 's_u_gb2312',s_u_gb2312,type(s_u_gb2312)
print 's_u_gb2312_u',s_u_gb2312_u,type(s_u_gb2312_u)
print 'gb2312_gbk_u',gb2312_gbk_u,type(gb2312_gbk_u)
print 'gb2312_gbk',gb2312_gbk,type(gb2312_gbk)
print 'gb2312_utf8',gb2312_utf8,type(gb2312_utf8)
Overwriting test4.py
!chmod 755 test4.py
!./test4.py
utf-8
s: 孙成全
u 孙成全
u_utf 孙成全
u_gb2312 ���ȫ
u_gb2312_u 孙成全
u_gb2312_u_utf8 孙成全
s_u 孙成全
s_u_gb2312 ���ȫ
s_u_gb2312_u 孙成全
gb2312_gbk_u 孙成全
gb2312_gbk ���ȫ
gb2312_utf8 孙成全
py3字符串也有两种数据类型:str和bytes; str类型存unicode数据,bytes类型存bytes数据,与py2比只是换了一下名字而已
Python3的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。
于是,在我们的文本编辑器软件都有默认的保存文件的编码方式,比如utf8,比如gbk。当我们点击保存的时候,这些编辑软件已经"默默地"帮我们做了编码工作。
那当我们再打开这个文件时,软件又默默地给我们做了解码的工作,将数据再解码成unicode,然后就可以呈现明文给用户了!所以,unicode是离用户更近的数据,bytes是离计算机更近的数据。
python3 的默认编码unicode
Python对bytes类型的数据用带b前缀的单引号或双引号表示:
x = b'ABC'
以Unicode表示的str通过encode()方法可以编码为指定的bytes,例如:
print('ABC'.encode('ascii'))
print('中文'.encode('utf-8'))
# print('中文'.encode('ascii'))
b'ABC'
b'\xe4\xb8\xad\xe6\x96\x87'
纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。
如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:
b'ABC'.decode('ascii')
'ABC'
b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
!which python
/root/miniconda3/bin/python
%%writefile test4.py
#!/root/miniconda3/bin/python
import sys
import json
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")
gb2312_to_utf8_unicode = msg_gb2312.decode("gb2312").encode("utf-8").decode("utf-8")
print('msg:',msg,type(msg),json.dumps(msg))
print('msg_gb2312:',msg_gb2312,type(msg_gb2312))
print('gb2312_to_unicode:',gb2312_to_unicode,type(gb2312_to_unicode))
print('gb2312_to_utf8:',gb2312_to_utf8,type(gb2312_to_utf8))
print('gb2312_to_utf8_unicode:',gb2312_to_utf8_unicode,type(gb2312_to_utf8_unicode))
Overwriting test4.py
!chmod 755 test4.py
!./test4.py
utf-8
msg: 孙成全 "\u5b59\u6210\u5168"
msg_gb2312: b'\xcb\xef\xb3\xc9\xc8\xab'
gb2312_to_unicode: 孙成全
gb2312_to_utf8: b'\xe5\xad\x99\xe6\x88\x90\xe5\x85\xa8'
gb2312_to_utf8_unicode: 孙成全
无论py2,还是py3,与明文直接对应的就是unicode数据,打印unicode数据就会显示相应的明文(包括英文和中文)
Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加
布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,可以直接用True、False表示布尔值(请注意大小写),也可以通过布尔运算计算出来
print(True)
print(False)
print(3 > 2)
print(3 > 5)
print(True + True)
True
False
True
False
2
布尔值可以用and、or和not运算。
and运算是与运算,只有所有都为True,and运算结果才是True
print(True and True)
print(True and False)
print(False and False)
print(5 > 3 and 3 > 1)
True
False
False
True
or运算是或运算,只要其中有一个为True,or运算结果就是True
print(True or True)
print(True or False)
print(False or False)
print(5 > 3 or 3 > 1)
True
True
False
True
not运算是非运算,它是一个单目运算符,把True变成False,False变成True
print(not True)
print(not False)
print(not 1 > 2)
False
True
True
布尔值经常用在条件判断中
age = 27
if age >= 18:
print('adult')
else:
print('teenager')
adult
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值