在 Python 中,共有六大基本数据类型:
其中,string, tuple 和 number 是不可更改的对象,而 list, dict 等则是可以修改的对象
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。传递的只是a的值,没有影响a对象本身,所以在函数 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。在函数中传值过去后,la的值也会改变
注:在Python的数据分析中,常用的数据类型为:Logical(逻辑型,即布尔型)、Numeric(数值型)、Character(字符型)
补充: -> 集合(collection)
集合(collection) != 集(set),集是一种Python中内建的数据类型,是一种集合类型,除此以外,集合还包括以下类型(图1)。那么,集合是什么?从用户和客户的视角来说,集合是在程序中的应用,如可以用字典来实现信息的带标签存储与按键取值、列表则可以应用于各种排序算法、包则实现了抽象等等;从开发者和实现者的视角来说,集合作为通用资源可广泛应用于开发程序、通过复杂度分析来提高性能,最常见的就是在数据结构的学习中可以发现,即使应用于解决索引冲突的哈希表(HashDict)、计算后缀表达式的链栈(LinkedStack) 等等的集合类型相互不同,但都基于六大基本数据类型而实现,同时都有抽象出来的 AbstractCollection(object) 类里边的初始化、取结果字符串、取长度等操作(表1)。
Python的数据结构学习中,基于AbstractCollection(object) 类而开发出的所有集合类型的伪接口见附录(附图-1),本文不做详解。
操作:
操作分类 | 说明 |
---|---|
确定大小 | 使用len() 函数获取集合中当前项的数目 |
测试项的成员关系 | 使用in 运算符在集合中搜索一个给定的目标项 |
遍历集合 | 使用for 循环访问集合中的每一项,访问顺序取决于集合的类型 |
获取一个字符串表示 | 使用str 函数来获取集合的字符串表示 |
测试相等性 | 使用== 运算符比较两集合间的项数及元素是否都相同 |
连接两个集合 | 使用+ 运算符 |
转化为另一种类型的集合 | 使用源集合中的相同项来创建另一个新的集合 |
插入一项 | 选择指定位置插入 |
删除一项 | 删除指定项 |
替换一项 | 将删除和插入组合到一项操作中 |
访问或获取一项 | 可能从某个给定的位置获取 |
数字类型分为三种:
整数类型共有4种进制:十进制、二进制、八进制和十六进制。我们在生活中常见的整数(如201,-13等),以及 Python中从键盘默认输入的,都是十进制;二进制常见于底层软件与硬件接口涉及到指令集、数电等方面,在一些算法题中也会用“01字符串”考察到双指针异或、hash等算法思维。表2给出了4种进制的表示
序号 | 进制种类 | 引导符号 | 描述 |
---|---|---|---|
1 | 十进制 | 无 | 从键盘上接受的默认情况 |
2 | 二进制 | 0b或0B | 由字符0和1组成,如 0b011 |
3 | 八进制 | 0o或0O | 由字符0到7组成,如0o670 |
4 | 十六进制 | 0x或0X | 由字符0到9、a到f(也即A到F)组成,如0xABC |
所有浮点数均带有小数部分,如-8.0,10.
,9.6E5;其中前两种为十进制表示法,后一种为科学计数法。
x = 11.8e-1 + 6j
y = 21
print("x的实部是%.3f,虚部是%d\n" % (x.real, x.imag))
# 输出为:x的实部是1.180,虚部是6
print("y的实部是%.3f,虚部是%d\n" % (y.real, y.imag))
# 输出为:y的实部是21.000,虚部是0
from math import *
a = -10.6
x, y = 10, 100
abs(a) # 10.6
fabs(a) # 10.6
exp(a) # 2.4916009731503204e-05
ceil(a) # -11
floor(a) # -10
(x > y) - (x < y) # 在Python2中为cmp(x, y),即x>y则返回1,x==y则返回0,反之则返回-1
log(4, 2) # 2.0
log10(y) == log(y, x) # True
min(x, y) # 10
max(x, y) # 100
round(a, 2) # -10.6
modf(a) # (-0.5999999999999996, -10.0)
sqrt(y) # 10.0
import cmath
import math
dir(cmath)
x, y = 24, 56
acos(0.41) # 返回x的反余弦弧度值:1.148342264608141
asin(0.41) # 返回x的反正弦弧度值:0.42245406218675574
atan(1) # 返回x的反正切弧度值:0.7853981633974483
atan2(0.41, 1) # 返回给定的 X 及 Y 坐标值的反正切值:0.3890972310552784
cos(x) # 返回x的弧度的余弦值:0.4241790073369969
hypot(x, y) # 返回欧几里德范数 sqrt(x*x + y*y) --60.92618484691127
sin(x) # 返回的x弧度的正弦值:-0.9055783620066239
tan(x) # 返回x弧度的正切值:-2.1348966977217008
degrees(math.pi/2) # 将弧度转换为角度,如degrees(math.pi/2) , 返回90.0
radians(x) # 将角度转换为弧度:0.4188790204786391
x = 96
int(x) # 将x转换为一个整数
float(x ) # 将x转换到一个浮点数
complex(3, 4) # 创建一个复数
str(x) # 将对象 x 转换为字符串
repr(x ) # 将对象 x 转换为表达式字符串
eval("x") # 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple([1, 2, 3]) # 将序列 s 转换为一个元组
list("1223") # 将序列 s 转换为一个列表
chr(x ) # 将一个整数转换为一个字符
ord('A') # 将一个字符转换为它的整数值
hex(x ) # 将一个整数转换为一个十六进制字符串
oct(x ) # 将一个整数转换为一个八进制字符串
from random import *
choice(range(10)) # 从序列中随机挑选一个数
randrange(1, 10, 3) # 在指定范围内,从按基数递增的集合中随机选取一个数
random() # random() takes no arguments, 随机生成一个[0,1)内的实数
seed() # 改变随机数生成器的种子,如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed
shuffle([]) # 将序列的所有元素随机排序
dir(random)
在Python中,字符型数据一般用单引号'ad'
或双引号"desk"
表示,两者无区别,但在C语言中,前者通常表示一个字符'e'
、后者表示一个字符串"Apple"
.
Python变量命名规则:
一些个小的拓展和建议:
- 四种命名法:
- 驼峰命名法:第一个单词首字母小写,后面其他单词首字母大写
- 帕斯卡命名法,又叫大驼峰式命名法:每个单词都要大写
- 匈牙利命名法:前缀字母用变量类型的缩写,省去元音字母
- 下划线命名法- 养成良好的编程习惯就应该先从写注释和变量命名开始,建议去社区中参考大厂(如华为)的命名规范,或者浏览工程师们的建议Link
- 虽然不同的函数的局部变量互不干扰,但建议最好避免同名变量;当全局变量和局部变量名字相同时,函数中使用的是局部变量
- 在OOP中,一个实例变量总有一个self前缀,与参数或临时变量不同,实例变量在类的任何方法中都是可见的,而命名一些类的实例变量时总是带有单下划线
- 单下划线命名变量只有类对象和子类对象能访问到,双下划线开头和结尾的变量表示Python里的特殊方法,只有类对象自己能访问到
以下是我的习惯命名法:
名称类型 | 变量 | 常量、全局变量 | 函数或方法 | 类 |
---|---|---|---|---|
示例 | 小写+驼峰,如salary, dataSets | 帕斯卡命名,ABSOLUTE_ZERO | 小驼峰,printResult,isEmpty | 大驼峰, BankAccount |
Python不支持单字符类型,单字符在 Python 中也是作为一个字符串使用
var1 = 'Hello World!'
var2 = "Python Runoob"
print(var1[0])
print(var2[1:5])
print("line1 \
… line2 \
… line3")
print("\' \''")
print("{:*^50}".format('格式化输出'))
a = "I love"
b = "Apple"
print(a+b)
print(a, "\u0020", b) # \u0020为空格字符
print(b * 2)
a = "apple"
string = 'HelloWorld'
a.capitalize() # 首字母大写,'Apple'
string.lower() # 转换 string 中所有大写字符为小写
string.upper() # 转换 string 中的小写字母为大写
string.swapcase() # 翻转 string 中的大小写
'i l u'.title() # 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
a.count('p', 0, len(a)) # S.count(sub[, start[, end]]) -> int, 统计某字符在字符串中的指定范围内出现的次数
a.center(20) # 以 width 的长度输出,字符居中、不足的用空格补齐
string.ljust(20) # 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
string.rjust(20) # 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
string.zfill(20) # 返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0
string.replace('l', 't', 2) # 把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.
string.expandtabs(tabsize=8) # 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8
'------'.join(a) # 以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
'dhakdka'.split(",", 5) # 以 str 为分隔符切片 string,如果 num 有指定值,则仅分隔 num+1 个子字符串
'I\u0020Love\rapple\n'.splitlines() # 按照行('\r', '\r\n', '\n')分隔,返回一个包含各行作为元素的列表,
# 如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
' ahdjdla'.lstrip() # 截掉 string 左边的空格
'ahdjdla '.rstrip() # 删除 string 字符串末尾的空格.
' ahdjdla '.strip() # 在 string 上执行 lstrip()和 rstrip()
a.encode(encoding='UTF-8', errors='strict') # 以指定的编码形式编码,errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。
# 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。
a.encode(encoding='UTF-8', errors='strict').decode(encoding='GB2312', errors='strict') # 以指定形式解码
string.endswith(a[0], 0, len(string)) # 第一个参数是str或a tuple of str, 判断某字符在字符串中的指定范围内的结尾处是否出现
string.startswith('H', 0, len(string)) # 第一个参数是str或a tuple of str, 判断某字符在字符串中的指定范围内的开头处是否出现
string.find('llo', 0, len(string)) # 检测 str 是否包含在 string,如果是返回开始的索引值,否则返回-1
string.index('el', 0, len(string)) # 跟find()方法一样,只不过如果str不在 string中会报一个异常ValueError
string.rfind('orld', 0, len(string)) # 类似于 find() 函数,返回字符串最后一次出现的位置,如果没有匹配项则返回 -1。
'llolloapp'.rindex('llo', 0, len('llolloapp')) # 类似于 index(),不过是返回最后一个匹配到的子字符串的索引号。
string.partition('llo') # 有点像 find()和 split()的结合体,从 str出现的第一个位置起,把字符串 string分成一个3元素的元组
# (string_pre_str,str,string_post_str),如果 string中不包含 str 则 string_pre_str == string, 后面为空
string.rpartition('llo') # 类似于 partition()函数,不过是从右边开始查找
string.isalnum() # 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
string.isalpha() # 如果 string 至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False
'3131'.isdecimal() # 如果 string 只包含十进制数字则返回 True 否则返回 False.
'3131'.isdigit() # 如果 string 只包含数字则返回 True 否则返回 False.
'1'.isnumeric() # 如果 string 中只包含数字字符,则返回 True,否则返回 False
' '.isspace() # 如果 string 中只包含空格,则返回 True,否则返回 False.
'I L U'.istitle() # 如果字符串中所有的单词拼写首字母是否为大写,且其他字母为小写则返回 True,否则返回 False.
string.isupper() # 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
a.islower() # 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
c = a.maketrans('ple', '*k&') # 该方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,
# 第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
string.translate(c) # 借助上一方法创建的字符替换对照表,将 string中的相应字符按对照表替换
max(a) # 返回字符串 str 中最大的字母。
min(a) # 返回字符串 str 中最小的字母。
# 列表可定义不同类型的数据,并且索引值是从0开始计数
name_list =['hello python','larissa','Alex',520,True]
# 取值与取索引
print(name_list[2])
print(name_list.index(520))
# 修改 or 替换 列表中的数据
name_list[0] = "hello world"
print(name_list)
# 增加
""" append 是在列表最后增添数据
insert 是在列表的指定位置插入数据
extend 用于在某一列表后拼接另一列表 """
name_list.append('1')
print(name_list)
print(len(name_list))
name_list.insert(2,'1')
print(name_list)
print(len(name_list))
another_list = ['1','2','3']
name_list.extend(another_list)
print(name_list)
# 删除
""" remove 可删除列表中指定数据
pop 在不传递数据的索引之前默认删除列表最后一个数据,在传递索引值后可删除索引值对应的数据
clear 可以清空列表的所有数据
del关键字本质上是将一个变量从内存中删除 """
name_list.remove(520)
print(name_list)
name_list.pop(2)
print(name_list)
name_list.clear()
print(name_list)
str = "nihao"
del str
print(str)
# 统计
"""len可统计列表中元素的个数
count可统计某一数据出现的次数"""
print(len(name_list))
name_list.append(520)
print(name_list.count(520))
# 排序
"""sort()升序
sort(reverse=True)降序
reverse()逆序/反序"""
str_list = ["wangwu","lisi","zhangsan"]
num_list = [1,3,9,5]
str_list.sort()
num_list.sort(reverse=True)
num_list.reverse()
print(num_list)
# 成员运算符
for x in [1, 2, 3]: print(x)
# 比较
# 导入 operator 模块
import operator
a = [1, 2]
b = [2, 3]
c = [2, 3]
print("operator.eq(a,b): ", operator.eq(a,b))
print("operator.eq(c,b): ", operator.eq(c,b))
# 使用迭代器接收键盘输入(以空格隔开)以创建一维数组
l1 = list(map(int, input("请输入整数:").split()))
"""创建二维数组"""
# 1. 一维复制法
a = [[]] * 3
a[0].append(1)
a[1].append(2)
a[2].append(3)
print(id(a[0]))
print(id(a[1]))
print(a)
b = [[] for i in range(3)]
b[0].append(1)
b[1].append(2)
b[2].append(3)
print(id(b[0]))
print(id(b[1]))
print(b)
# 2. 直接创建法
a1 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
print(a1)
# 3. numpy库调用
import numpy as np
a2 = np.zeros((3, 3))
print(a2)
# 列表推导式:
# [表达式 for 变量 in 列表]
# [out_exp_res for out_exp in input_list]
names = ["Alex", "Bob", "Clara", "Davie", "Eve"]
new = [name.upper() for name in names if len(names) > 3]
print(new)
# 0-100 中可以被2整除的数作为一个列表
num = [i for i in range(100) if i % 2 == 0]
print(num)
# 遍历列表
s2 = ['name', 'num', 'score']
s3 = ['Alex', 1001, 91.5]
for index, val in enumerate(s2):
print(index, '(index)', val, '(value)')
for i, j in zip(s2, s3):
print(i, '->', j)
# 使用迭代器接收键盘输入(以空格隔开)、创建元组/数组嵌套的一维数组
Tl1, Ll2 = [], []
for i in range(6):
x, y = list(map(int, input("请输入两个整数:").split()))
Tl1.append((x, y)) # 嵌套元组 -- 数据不可修改
Ll2.append([x, y]) # 嵌套列表 -- 数据可以修改
包含初始化、索引切片、风格排序、增删改(求值)查、改变形状(广播机制、堆叠、分割等),详见系列文章 【NumPy入门】
import numpy as np
a = np.array([1,2,3])
print (a)
# 多于一个维度
import numpy as np
a = np.array([[1, 2], [3, 4]])
print (a)
# 最小维度
import numpy as np
a = np.array([1, 2, 3, 4, 5], ndmin = 2)
print (a)
import numpy as np
# 举例。注意 − 数组元素为随机值,因为它们未初始化。
x = np.empty([3,2], dtype = int)
print (x)
# 举例。 设置类型为整数
y = np.zeros((5), dtype = int)
print(y)
# 举例。默认为浮点数
x = np.ones(5)
print(x)
# 举例。注意:参数a可以是任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
x = [1,2,3]
a = np.asarray(x)
print (a)
#生成 0 到 5 的数组:
x = np.arange(5)
print (x)
#设置了起始值、终止值及步长:
x = np.arange(10,20,2)
print (x)
# np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
a = np.linspace(10, 20, 5, endpoint = False)
print(a)
# np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
# 默认底数是 10
a = np.logspace(1.0, 2.0, num = 10)
print (a)
# 创建元组, 注:python2中任意无符号的对象,以逗号隔开,默认为元组
tup0 = (50)
print(type(tup0)) # 不加逗号,类型为整型
tup0 = (50,)
print(type(tup0)) # 加上逗号,类型为元组
# 拼接两个元组
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
tup3 = tup1 + tup2
print (tup3)
# 返回元组中的最值
max(tup1), min(tup1)
# 元组的不可变指的是元组所指向的内存中的内容不可变,但可以针对整个元组进行重新赋值或删除
tup = ('r', 'u', 'n', 'o', 'o', 'b')
id(tup) # 查看内存地址
4440687904
tup = (1,2,3) #重新赋值
id(tup)
4441088800 # 内存地址不一样了
# 整体删除
tup = ('Google', 'Runoob', 1997, 2000)
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)
# 查
# 01取值与取索引
info_tuple = ("zhangsan", 54, "wangwu", "wangwu")
print(info_tuple[1])
print(info_tuple.index("zhangsan"))
# 02计算某个数据出现的次数
print(info_tuple.count("wangwu"))
# 键(key)是索引,必须是字符串、数字、元组,且唯一;值(value)是数据,不一定唯一。字典无序
info_dict = {"name":"张三",
"age":18,
"gender":"boy"}
# 01取值
print(info_dict["name"])
# 02增加 and 修改
""" 当键(key)在字典中不存在时,会增加键值对
当键(key)在字典中存在时,会修改原来的值 """
info_dict["height"] = 1.75
info_dict["name"] = "李四"
s = info_dict.copy() # 浅复制
# 03删除
info_dict.pop("gender")
info_dict.popitem() # 返回并删除字典中的最后一对键和值。
del info_dict['name'] # 删除 name 的条目
# del info_dict # 删除整个字典
# 04统计键值对的数量
print(len(info_dict))
# 05判断键是否在字典中,在则返回True,如果值不在字典中返回False
info_dict.__contains__('name')
'name' in info_dict
# 06合并字典
""" 注意,当被合并的字典中出现原已存在的键值对时,会覆盖原来的值 """
temp_dict = {"age":20,
"country":"China"}
info_dict.update(temp_dict)
# 07清空字典
info_dict.clear()
print(info_dict)
# 08遍历字典
s1 = {'name':'Alex', 'num':1001, 'score':91.5}
s1.items()
for k,v in s1.items():
print(k, '->', v)
s1 = {'name':'Alex', 'num':1001, 'score':91.5}
s2 = dict
s2.fromkeys(('name', ), ('Bob', 'Clara', 'Dylan')) # 创建一个新字典,以第一个参数序列元素做字典的键,第二个参数为字典所有键对应的初始值
s1.get('num') # 返回指定键的值,如果值不在字典中返回default值
s1.values() # 以列表返回字典中的所有值
s1.setdefault('num') # 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
s1.copy() # 返回一个字典的浅复制
s1.items() # 遍历字典中的所有键值对
s1.update({'name':'Bob', 'Country':'China'}) # 把字典dict2的键/值对更新到dict里
s1.popitem() # 返回并删除字典中的最后一对键和值
s1.pop('score') # 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
s1.__contains__('name') # 判断键是否在字典中,在则返回True,如果值不在字典中返回False;Python2中用has_key()函数
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket) # 这里演示的是去重功能
# 列表去重方法 --转化成集
l1 = [22, 22, 41, 17, 6, 22, 3]
l1 = list(set(l1))
print(l1)
a = set('abracadabra')
b = set('alacazam')
print(a) # >>> {'a', 'r', 'b', 'c', 'd'} 天生去重
print(a - b ) # >>> {'r', 'd', 'b'} 集a中包含而集b中不包含的元素
print(a | b) # >>> {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} 集a或b中包含的所有元素
print(a & b) # >>> {'a', 'c'} 集a和b中都包含了的元素
print(a ^ b) # >>> {'r', 'd', 'b', 'm', 'z', 'l'} 不同时包含于a和b的元素
# 法一:
tinyset = set(("Google", "Baidu", "Yamaxun"))
tinyset.add("Facebook")
print(tinyset) # >>> {'Taobao', 'Facebook', 'Google', 'Runoob'}
# 法二:参数可以是列表,元组,字典等
tinyset = set(("Google", "Runoob", "Taobao"))
tinyset.update({1,3})
print(tinyset) # >>> {1, 3, 'Google', 'Taobao', 'Runoob'}
tinyset.update([1,4],[5,6])
print(tinyset) # >>> {1, 3, 4, 5, 6, 'Google', 'Taobao', 'Runoob'}
# 法一:s.remove(x)
tinyset = set(("Google", "Baidu", "Yamaxun"))
tinyset.remove("Baidu")
print(tinyset) # >>> {'Google', 'Runoob'}
# tinyset.remove("Facebook") # >>> 不存在会发生错误
# 法二:s.discard(x)
tinyset.discard('Google')
print(tinyset)
# 法三:s.clear()清空
tinyset.clear()
print(tinyset)
tinyset = set(("Google", "Baidu", "Yamaxun"))
tinyset = set(list(tinyset).pop(2))
print(tinyset)
tinyset = set(("Google", "Baidu", "Yamaxun"))
print( "Yamaxun" in tinyset) # >>> True
print( "Facebook" in tinyset) # >>> False