一、公共方法 1.python内置函数(不需要通过import导入模块就可以通过函数名直接调用的函数)
针对高级数据类型的内置函数(这里指列表、元组、字典、字符串) del的关键字和函数方式
>>> a = [1,2,3]
>>> del a[1]//关键字
>>> a
[1, 3]
>>> del(a[1])//函数
>>> a
[1]
>>> del a//或者del(a)都可以删除a变量,再输出就会提示a没有被定义
>>> a
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
a
NameError: name 'a' is not defined
最大最小值
>>> t_str = "arytorrqwpeursgflksgsdfg;"
>>> max(t_str)
'y'
>>> min(t_str)
';'
>>> t_list = [2,4,6,56,43]
>>> max(t_list)
56
>>> min(t_list)
2
>>> t_dict = {"a": "z", "b": "y", "c": "x"}
>>> max(t_dict)//如果是字典比较的是key值
'c'
>>> min(t_dict)
'a'
字符串比较符合以下规则:“0” < “A” < “a”
比较两个值的大小使用>, < ,==
//python3.x中取消了cmp函数
>>> cmp("1", "2")
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
cmp("1", "2")
NameError: name 'cmp' is not defined
>>> "1" > "2"
False
>>> "zasdf" > "zbsdf"
False
>>> [1,2,3] < [2,3,4]
True
>>> (1,2,3) < (1,2,3,4)
True
>>> "1" == "1"
True
字典和字典不能比较大小
>>> {"a": "z"} < {"b": "y"}
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
{"a": "z"} < {"b": "y"}
TypeError: '<' not supported between instances of 'dict' and 'dict'
2.切片 字符串、列表、元组支持切片;【通过索引值获取到对应的数据】
>>> [0,1,2,3,4][1:3]
[1, 2]
>>> (0,1,2,3,4)[1:3]
(1, 2)
>>> "01234"[1:3]
'12'
字典类型不支持切片; (字典是无序集合,使用键值对保存数据)【字典中没有索引的概念】
>>> {"a": "a", "b": "b"}[0:1]
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
{"a": "a", "b": "b"}[0:1]
TypeError: unhashable type: 'slice'
3.运算符
python中,字符串、列表、元组都可以使用乘号进行重复,但是字典不支持重复,因为如果乘号有效,那么字典中就会有多个key相同的元素,不符合字典的key唯一的原则。
>>> [1,2]*5
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
>>> (1,2) * 5
(1, 2, 1, 2, 1, 2, 1, 2, 1, 2)
>>> "12"*5
'1212121212'
>>> {"a": "z"} * 3
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
{"a": "z"} * 3
TypeError: unsupported operand type(s) for *: 'dict' and 'int'
列表的 +运算符合并和extend方法合并:+会产生一个新的列表; extend方法会把指定的列表参数合并到当前列表中; append方法会把指定的列表参数当成一个独立的元素追加到当前列表末尾;
>>> "hello" + "python"
'hellopython'
>>> (1,2) + (1,2)
(1, 2, 1, 2)
>>> [1,2] + [3,4]
[1, 2, 3, 4]
>>> (1,2) + [2,3]
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
(1,2) + [2,3]
TypeError: can only concatenate tuple (not "list") to tuple
//列表的extend方法
>>> t_list = [1,2]
>>> t_list.extend([2,3])
>>> t_list
[1, 2, 2, 3]
//extend方法会把指定的列表参数合并到当前列表中。
>>> t_list.append(0)
>>> t_list
[1, 2, 2, 3, 0]
>>> t_list.append([8,9])
>>> t_list
[1, 2, 2, 3, 0, [8, 9]]
//append方法会把指定的列表参数当成一个独立的元素追加到当前列表末尾
in和 not in判断某一个元素是否包含在序列中。 in和not in被称为成员运算符。 in在对字典操作时,判断的是字典的键。
>>> "a" in "avsa"
True
>>> "a" not in "afd"
False
>>> 1 in [1,2,3]
True
>>> 1 not in [1,2,3]
False
>>> "a" in ("a","b")
True
>>> "a" in {"a" : "laowang"}
True
>>> "laowang" in {"a": "laowang"}
False
4.for循环
for 变量 in 集合:
循环体代码
else:
没有通过break退出循环,循环结束后会执行的代码
如果在循环体中使用了break退出for循环(集合没有遍历完成),那么else部分的代码就不会被执行。 只有集合从头到尾遍历完成,else部分的代码才会被执行。
for num in [1, 2, 3]:
print(num)
else:
print("遍历完成")
for num in [1, 2, 3]:
print(num)
if num == 2:
break
else:
print("遍历完成")
for循环的应用场景: 在迭代遍历嵌套的数据类型时,例如一个列表包含了多个字典需求:要判断某一个字典中是否存在指定的值
- 如果存在,提示并且退出循环
- 如果不存在,在循环整体结束后,希望得到一个统一的提示
利用for else搜索字典列表
students = [{"name": "小明"},
{"name": "小红"}]
find_name = "小是"
for stu_dict in students:
print(stu_dict)
if stu_dict["name"] == find_name:
print("找到了 %s" % find_name)
break
else:
print("没有找到 %s" % find_name)
5.综合应用-名片管理系统 (1)文件准备 新建cards_main.py保存主程序功能代码–程序的入口;每一次启动名片管理系统都通过main这个文件启动;
新建cards_tools.py保存所有名片功能函数–将对名片的新增、查询、修改、删除等功能封装在不同的函数中
TODO注释 在# 后跟上TODO,用于标记需要去做的工作。(给自己提示) # TODO(作者/邮件) 显示系统菜单 在PyCharm中,TODO注释会变蓝加粗,醒目。这样就不容易遗忘还没完善的功能。
如果在开发程序时,不希望立刻编写分支内部的代码,可以使用pass关键字,表示一个占位符,这样就能够保证程序的代码结构正确。并且程序运行时,pass关键字不会执行任何的操作。【pass就是一个空语句,不作任何事情,一般用作占位语句,这样可以保持程序结构的完整性】
while True: 无限循环保证用户能够重复操作,由用户主动决定什么时候退出循环(此例使用break)。
if action in [“1”, “2”, “3”] 而非 if action==“1” or action==“2” or action==“3” ,使用in针对列表判断,避免使用or拼接复杂的逻辑条件。并且这里没有使用int转换用户输入,可以避免一旦用户输入的不是数字,导致程序运行出错。—字符串判断的技巧
(2)数据结构 使用字典记录每一张名片的详细信息。 使用列表统一记录所有的名片字典。
在cards_tools文件的顶部增加一个列表变量. 所有名片相关操作,都需要使用这个列表,所以应该定义在程序的顶部;程序刚运行时,没有数据,所以是空列表。
card_list = []
PyCharm技巧-重命名变量 将光标定位到某一个变量名,右键,选择refactor-rename-rename codel occurrences(rename all occurrences会修改所有出现变量名字样的地方),只修改变量名。
return关键字,可以返回一个函数的执行结果,并且其下方的代码不会被执行。
函数编写完成之后,要删除TODO注释(只删掉TODO即可),并且添加文档注释。光标定位到函数名,在小灯泡上选择 Insert documentation string stub
(3)完整程序
在Linux终端中运行py文件,python3 cards_main.py; 或者如果这个py文件是可执行的,则 ./cards_main.py;
Linux上的Shebang符号(#!) #!这个符号通常在UNIX系统脚本的第一行开头使用; 指明执行这个脚本的解释程序;
Shebang的使用步骤 a. 使用which查询python3解释器所在路径 $ which python3 b. 修改要运行的主python文件,在第一行增加以下内容 #! /usr/bin/python3 c. 修改主python文件的文件权限,增加执行权限 $ chmod +x cards_main.py d. 在需要时执行程序即可 ./cards_main.py
card_main.py
import cards_tools
while True:
cards_tools.show_menu()
action_str = input("请选择希望执行的操作:")
print("您选择的操作是【%s】" % action_str)
if action_str in ["1", "2", "3"]:
if action_str == "1":
cards_tools.new_card()
elif action_str == "2":
cards_tools.show_all()
elif action_str == "3":
cards_tools.search_card()
pass
elif action_str == "0":
print("欢迎再次使用【名片管理系统】")
break
else:
print("您输入的不正确,请重新选择")
card_tools.py
card_list = []
def show_menu():
"""显示菜单"""
print("*" * 50)
print("欢迎使用【名片管理系统】V 1.0")
print("")
print("1.新增名片")
print("2.显示全部")
print("3.搜索名片")
print("")
print("0.退出系统")
print("*" * 50)
def new_card():
"""新增名片"""
print("-" * 50)
print("新增名片")
name_str = input("请输入姓名:")
phone_str = input("请输入电话:")
qq_str = input("请输入QQ:")
email_str = input("请输入邮箱:")
card_dict = {"name": name_str,
"phone": phone_str,
"qq": qq_str,
"email": email_str}
card_list.append(card_dict)
print(card_list)
print("添加%s的名片成功" % name_str)
def show_all():
"""显示所有名片"""
print("-" * 50)
print("显示所有名片")
if len(card_list) == 0:
print("当前没有任何的名片记录,请使用新增功能添加名片")
return
for name in ["姓名", "电话", "QQ", "邮箱"]:
print(name, end="\t\t")
print("")
print("=" * 50)
for card_dict in card_list:
print("%s\t\t%s\t\t%s\t\t%s\t\t" % (card_dict["name"],
card_dict["phone"],
card_dict["qq"],
card_dict["email"]))
def search_card():
"""搜索名片"""
print("-" * 50)
print("搜索名片")
find_name = input("请输入要搜索的姓名:")
for card_dict in card_list:
if card_dict["name"] == find_name:
print("姓名\t\t电话\t\tQQ\t\t邮箱\t\t")
print("=" * 50)
print("%s\t\t%s\t\t%s\t\t%s\t\t" % (card_dict["name"],
card_dict["phone"],
card_dict["qq"],
card_dict["email"]))
deal_card(card_dict)
break
else:
print("抱歉没有找到%s" % find_name)
def deal_card(find_dict):
"""处理查找到的名片
:param find_dict:查找到的名片
"""
print(find_dict)
action_str = input("请选择要执行的操作 "
"[1]修改 [2]删除 [0]返回上级菜单")
if action_str == "1":
find_dict["name"] = input_card_info(find_dict["name"], "姓名:")
find_dict["phone"] = input_card_info(find_dict["phone"], "电话:")
find_dict["qq"] = input_card_info(find_dict["qq"], "QQ:")
find_dict["email"] = input_card_info(find_dict["email"], "邮箱:")
print("修改名片成功")
elif action_str == "2":
card_list.remove(find_dict)
print("删除名片成功")
def input_card_info(dict_value, tip_message):
"""输入名片信息
:param dict_value:字典中原有的值
:param tip_message:输入的提示文字
:return:如果用户输入了内容,就返回内容,否则返回字典中原有的值
"""
result_str = input(tip_message)
if len(result_str) > 0:
return result_str
else:
return dict_value
二、变量进阶 1.变量的引用 (1)变量和数据都是保存在内存中的; 在python中函数的参数传递以及返回值都是靠引用传递的。 (2)引用 python中,变量和数据是分开存储的,数据保存在内存中的一个位置,变量中保存着数据在内存中的地址。
变量中记录数据的地址,就叫做引用。
使用id()函数可以查看变量中保存数据所在的内存地址。
如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用。(变量不再对之前的数据引用,而是改为对新赋值的数据引用)
>>> a = 1
>>> id(a)
2564971391280
>>> id(1)
2564971391280
>>> b = a
>>> id(b)
2564971391280
//数据1的地址,变量a保存的数据的地址和变量b保存的数据的地址都一样。
调用函数,本质上传递的是实参保存的数据的引用,而不是实参保存的数据。 函数的返回值返回的是数据的引用,而不是数据的本身。
def test(num):
print("在函数内部%d对应的内存地址是%d" % (num, id(num)))
result = "hello"
print("函数要返回数据的内存地址为%d" % id(result))
return result
a = 10
print("a变量保存数据的内存地址是%d" % id(a))
r = test(a)
print("%s的内存地址是%d" % (r, id(r)))
2.可变和不可变类型 (1)不可变类型(内存中的数据不允许被修改):
- 数字类型int,bool,float,complex,long(2,x)
- 字符串str
- 元组tuple
(2)可变类型(内存中的数据可以被修改)
- 列表list(如append,pop,remove,clear方法)
- 字典dict
(3)列表、字典的修改和赋值
a = 1
a = "hello"
a = [1,2,3]
a = [3,2,1]
//改变a变量的引用地址
可变类型的数据变化,是通过方法来实现的。
注意:字典的key只能使用不可变类型的数据。
针对列表,我们使用方法修改数据并不会影响列表在内存中的地址。而一旦使用赋值语句,就意味着将标签从原有的列表上撕下来粘到新的列表上。
如果给一个可变类型的变量,赋值了一个新的数据,引用会修改:变量不再对之前的数据引用,而是改为对新赋值的数据引用。
>>>
>>> a = [1,2,3]
>>> id(a)
2565011343936
>>> a.append(999)
>>> a
[1, 2, 3, 999]
>>> id(a)
2565011343936
>>> a.remove(2)
>>> a
[1, 3, 999]
>>> id(a)
2565011343936
>>> a.clear()
>>> a
[]
>>> id(a)
2565011343936
>>> a = []
>>> id(a)
2565011221248
>>>
>>> d = {"name": "xiaoming"}
>>> d
{'name': 'xiaoming'}
>>> d["age"] = 18
>>> d
{'name': 'xiaoming', 'age': 18}
>>> id(d)
2564976905792
>>> d.pop("age")
18
>>> d
{'name': 'xiaoming'}
>>> id(d)
2564976905792
>>> d.clear()
>>> d
{}
>>> id(d)
2564976905792
>>> d = {}
>>> id(d)
2564976939904
(4)字典的key不能是可变类型 key可以是数字、字符串、元组,但是不能是列表或字典。
>>> d = {}
>>> d
{}
>>> d["str"] = "字符串"
>>> d[1] = "整数"
>>>> d[(1,)] = "元组"
>>> d
{'str': '字符串', 1: '整数', (1,): '元组'}
>>> d[[1,2]] = "列表"
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
d[[1,2]] = "列表"
TypeError: unhashable type: 'list'
//不能使用列表作为键值对的key
>>> d[{"n": "xxx"}] = "字典"
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
d[{"n": "xxx"}] = "字典"
TypeError: unhashable type: 'dict'
//不能使用字典作为键值对的key
字典的键值对的key只能是不可变类型。 (5)[扩展] 哈希hash python中内置有一个名字叫做hash(o)的函数:接收一个不可变类型的数据作为参数,返回结果是一个整数。
哈希是一种算法,其作用就是提取数据的特征码(指纹),相同的内容得到相同的结果,不同的内容得到不同的结果。
在python中,设置字典的键值对时,会首先调用hash()对key进行hash以决定如何在内存中保存字典的数据,以便后续对字典的增删改查。【hash函数的参数只能是不可变类型,所以key也只能是不可变类型】
键值对的key必须是不可变类型数据; 键值对的value可以是任意类型的数据。
>>> hash(1)
1
>>> hash(2)
2
>>> hash(10000)
10000
>>> hash("hello")
3327940101951472101
>>> hash("hello")
3327940101951472101
>>> hash("hello1")
7628699695339300285
>>> hash((1,"元组"))
-3166618364120721128
//hash()的参数不能是列表(可变类型)
>>> hash(["列表"])
Traceback (most recent call last):
File "<pyshell#59>", line 1, in <module>
hash(["列表"])
TypeError: unhashable type: 'list'
//hash()的参数不能是字典(可变类型)
>>> hash({"type":"字典"})
Traceback (most recent call last):
File "<pyshell#60>", line 1, in <module>
hash({"type":"字典"})
TypeError: unhashable type: 'dict'
3.局部变量和全局变量 (1)局部变量是在函数内部定义的变量,只能在函数内部使用; 函数执行结束后,函数内部的局部变量会被系统回收; 不同的函数,可以定义相同名字的局部变量,但是相互不会产生影响。
局部变量的生命周期: 生命周期:变量从被创建到被系统回收的过程; 局部变量在函数执行时才会被创建; 函数执行结束后局部变量被系统回收; 局部变量在生命周期内,可以用来存储函数内部临时使用到的数据;
不同函数内的同名局部变量
(2)全局变量是在函数外部定义的变量,所有函数内部都可以使用这个变量。
函数执行时,如果需要处理变量,则会:首先查找函数内部是否存在指定名称的局部变量,如果有直接使用;如果没有查找函数外部是否存在指定名称的全局变量,如果有直接使用;如果还没有,程序报错。
函数不能直接修改全局变量的引用:在函数内部,可以通过全局变量的引用获取对应的数据,但是不允许直接修改全局变量的引用(也就是不能使用赋值语句修改全局变量的值)
在其他开发语言中,大多不推荐使用全局变量,因为可变范围太大,导致程序不好维护。但是python对于全局变量的使用有了一些特殊的规定。
num = 10
def demo():
num = 99
print("demo->%d" % num)
demo()
为了保证所有的函数都能够正确使用到全局变量,应该将全局变量定义在其他函数的上方。
全局变量的命名:看具体的要求格式。(比如有些要求全局变量名前应该增加g_或者gl_的前缀)
如果局部变量的名字和全局变量的名字相同,那么PyCharm会在局部变量下方显示一个灰色的虚线。
(3)在函数内部修改全局变量的值 如果在函数中需要修改全局变量,需要使用global关键字进行声明。
(4)python文件的代码结构 shebang用来标识用哪一个解释器来解释当前python文件。
|