Python基础篇--【2022全新总结】

上一篇

9.对象和值

下面的a和b有两种可能的状态
一种可能是,a 和b 引用着不同的对象,它们的值相同。另一种情况下,它们指向同
一个对象。

a = 'stan'
b = 'stan'
# 判断a和b是否指向同一个字符串
print(a is b)
# 很明显是指向的同一个地址
print(id(a),id(b))

对一个列表进行修改

t4 = [1,2 ,4]
def bad(t):
    t = t[1:]
    return t
# 这个函数不会改变外面的t4,
print(bad(t4))
print(t4)

🚩在bad的开头,t 和t4 指向同一个列表。在函数最后,t 指向了一个
新的列表,但t4 仍然指向原先的那个没有改变的列表。

这个函数不会修改原始列表。

t4 = [1,2 ,4]
def tail(t):
    return t[1:]
t = tail(t4)
print(t)

range的使用

数range()让你能够轻松地生成一系列的数字

举个栗子

li = list(range(1, 10))
print(li)

步长

range(起始位置:结束位置:步长)
默认步长是1
起始位置 < 结束位置,步长是正数
起始位置 > 结束位置,步长是负数
步长为负数实现倒序排列

li = list(range(1, 10, 2))
print(li)
li = list(range(10, 0, -1))
print(li)
li = list(range(10, 0, -1))
print(li)

11.元组

目标

  1. 展示列表、字典和元组三者如何一起工作。
  2. 很有用的可变长参数列表功能:收集操作符和分散操作符。

(1)不可变

元组是值的一个序列。其中的值可以是任何类型,并且按照整数下标索引,所以从这 方面看,元组和列表很像。元组和列表之间的重要区别是,元组是不可变的。

语法:

# 元组就是用(逗号)分隔的一列值(有的话需要仔细的琢磨哦~)
t = '1', '3', 5, 9
print(t)
# 虽然不是必需的,但是我们常常用括号括起来
t = ('1', '3', 5, 9)
print(t)

如果你想输出一个元素的元组

t1 = ('1')
t2 = '1',
print(t1)
print(type(t1))
print(type(t2))
t3 = tuple(t1)
print(t3)

运行上面的代码,找不同。

🚩小结:

元组就是用(逗号)分隔的一列值,上面的代码可以看出,使用tuple方法后,t1输出的值是 ('1',)


如果参数是一个序列(字符串、列表或者元组),结果就是一个包含序列的元素的元 组:

st = tuple('lupins')

print(st)

在这里插入图片描述

❌因为tuple 是内置函数的名称,所以应当避免用它作为变量名称。

运算符使用

关系运算符适用于元组和其他序列。

print( (0, 1, 2) < (0, 3, 4))

Python从比较每个序列的第一个元素开始。如果 它们相等,它就继续比较下一个元素,依次类推,直到它找到不同元素为止。

(2)元组赋值

在做算法题时,时常会用到交换两个变量的值,传统的赋值方式,需要使用一个临时变量。

a = 2
b = 3
# 交换值
temp = a 
a = b
b = temp

这种解决方案很笨拙,而元组赋值 则更优雅:

a = 2
b = 3
a, b = b, a

print(a, b)

🚩 第三行,左边是一个变量的元组,右边是表达式的元组,。每个值会被赋值给相应的变量。右边 所有的表达式,都会在任何赋值操作进行之前完成求值。类似得用法很多,需要自己在实践中摸索,大胆实践。

⚠但是左右两边的值的个数必须得相同

❌a, b = 1,2,3

(3)作为返回值的元组

严格的讲,函数只能返回一个值,但如果返回值是元组的话,效果和返回多个值差不 多。例如,如果将两个整数相除,得到商和余数,那么先计算x/y 再计算x%y 并不高效。 更好的方法是同时计算它们。

python内置函数:divmod接收两个参数,并返回两个值的元组,即商和余数。可以将结果存 为一个元组:

builtins.py内置函数:

def divmod(x, y): # known case of builtins.divmod
    """ Return the tuple (x//y, x%y).  Invariant: div*y + mod == x. """
    return (0, 0)

使用:

t = divmod(7,3)
print(t)

结果:
image-20220524142937446

或者可以使用元组赋值来分别存储结果中的元素

val, mod = divmod(7,3)
print(mod)

来演示一个冗余的操作,主要是利于理解

def mod_val(a,b):
	val, mod = divmod(a,b)
	return val,mod

print(mod_val(7,3))
#最后得到的结果和上面元组赋值一样的,但是这里想展示的是返回一个元组的函数

(4)可变长参数元组

函数可以接收不定个数的参数。以* 开头的参数名会收集 (gather)所有的参数到一 个元组上。

来写一个接收任意个数的参数并打印它们:

def print_all(*args):
    print(args)

print_all("231adadsdad",2312)
#回得到一个元组

还是以divmod这个函数为例:

收集的反面是分散 (scatter)。如果有一个序列的值而想将它们作为可变长参数传入 到函数中,可以使用* 操作符。

因为divmod只允许传入两个值,所以我们不能传入元组,不信可以试试。但是我们可以将元组分散:

t = (7 , 3)
tt = divmod(*t)
print(tt)

结果:

image-20220524152038806

🚩python很多内置函数都是提供可变长参数元组,比如max,查看方法:在pycharm里面按住CTRL再鼠标左点。

image-20220524144555101

(5)列表和元组

zip 是一个内置函数,接收两个或多个序列,并返回一个元组列表。每个元组包含来 自每个序列中的一个元素。这个函数的名字取自拉链(zipper),它可以将两行链牙交替 连接起来。

(6)序列的序列

列表比元组更加通用,主要因为它是可变的。但也有一些情况下你可能会优先选择元 组。

  1. 在有些环境中,如返回语句中,创建元组比创建列表从语法上说更容易。
  2. 如果需要用序列作为字典的键,则必须使用不可变类型,如元组或字符串。
  3. 如果你要向函数传入一个序列作为参数,使用元组可能会减少潜在的由假名导致 的不可预知行为。

🚩因为元组是不可变的,它们不提供类似sort 和reverse 之类的方法,这些方法修改 现有的序列。但Python也提供了内置函数sorted ,可以接收任何序列作为参数,并按排 好的顺序返回带有同样元素的新列表。

1.字典

主要介绍三种存储方式

存储字典的列表、存储列表的字典和存储字典的字典。
字典是没有索引的

(1)去重

字典自动去掉相同键的键值对

alien_0 = {'color': 'green', 'points': 5, 'points': 5}

print(alien_0)

(2)访问字典的值和修改

没什么好说的这些

alien_0 = {'color': 'green', 'points': 5, 'points': 5}

alien_0['name'] = 'stan'
alien_0['character'] = 'outgoing'
alien_0['family'] = ['1', '2']
print(alien_0['family'])

(3)删除键值对

对于字典中不再需要的信息,可使用del语句将相应的键—值对彻底删除。使用del语句时,
必须指定字典名和要删除的键。

(4)字典做计数器

统计字符串中字母的个数

def hub(x):
    d =dict()
    for i in x :
        if i in d :
            d[i] += 1
        else:
            d[i] = 1
    return d

print(hub("aacde"))

(5)反向查找

给定一个字典d 和键k ,找到对应的值v = d[k] 非常容易。这个操作称为查找
(lookup)。
但是如果有v ,而想找到k 时怎么办?这里有两个问题:首先,可能存在多个键映射
到同一个值v 上。随不同的应用场景,也许可以挑其中一个,或者也许需要建立一个列表
来保存所有的键。其次,并没有可以进行反向查找 的简单语法,你需要使用搜索(如果你学过二分查找,
那么就可以找到你需要的值了)

alien_0 = {'color': 'green', 'points': 5, 'singer':'drake','age':5}
# 找到的第一个符合条件的数
def reverse (d, v):
    for k in d:
        if d[k] == v:
            return k
    raise LookupError()

print(reverse(alien_0, 5))

🚩raise 语句 会生成一个异常;在这个例子里它生成一个LookupError
,这是一个内置异常,通常用来表示查找操作失败。(不懂先不用管,或者百度)

(6)字典与列表

来做一个小栗子:

例如,如果你遇到一个将字母映射到频率的字
典,可能会想要反转它;也就是说,建立一个字典,将频率映射到字母上。因为可能出现
多个字母频率相同的情况,在反转的字典中,每项的值应当是字母的列表。

# 统计每个字母出现的次数
def hub(x):
    d =dict()
    for i in x :
        if i in d :
            d[i] += 1
        else:
            d[i] = 1
    return d

print(hub("aacde"))
st = 'stanabcc'
s = hub(st)

def inver_dict(d):
    save = dict()
    for key in d:
        val = d[key]
        if val not in save:
            # 将key作为列表添加进去
            save[val] = [key]
        else:
            save[val].append(key)
    return save

print(inver_dict(s))

image-20220523214035565

❌列表可以用作字典的值,但它们不能用作键。

image-20220523215118674

🚩小结:

字典是通过散列表的方式实现的,这意味着键必须是可散列 (hashable)的。散列 是一个函数,接收(任意类型)的值并返回一个整数。字典使用这些被称为散列值的整数来保存和查找键值对。

因此键必须是可散列的,而类似列表这样的可变类型是不可散列的。绕过这种限制的 最简单办法是使用元组。

因为字典是可变的,它也不能用作键,但它可以 用作字典的值。

(7)备忘

在3_函数-(4)执行流程中,我们写了求斐波那契数的代码

image-20220523222242695

从图中可以看出fib(1)和fib(0)被计算了很多次,而且当参数变大时,事情会变得更糟,一个解决办法是记录已经计算过的值,并将它们保存在一个字典中。将之前计算的值 保存起来以便后面使用的方法称为备忘 (memo)

known = {0:0, 1:1}
def fibonacci(n):
    if n in known:
        return known[n]
    res = fibonacci(n-1) + fibonacci(n-2)
    known[n] = res
    return res

先解释下代码:

每当fibonacci 被调用时,它会先检查known 。如果结果已经存在,则可以立即返 回。如果不存在,它需要计算这个新值,将其添加进字典,并返回。

我们将0和1保存下来, 提高了计算的效率,(当然这个不是最优的,别杠,这里只是为了用来展示字典的用法)

2.遍历字典⚠

alien_0 = {'color': 'green', 'points': 5}

# 添加值
alien_0['name'] = 'stan'
alien_0['character'] = 'outgoing'
alien_0['family'] = ['1', '2']

# 删除值
del alien_0['points']


# 输出字典
print(alien_0)
print(alien_0['family'])

for i, j in alien_0.items():
    print("key:",i,"value:",j)

print("*"*11)
# 得到的是键,可以通过键得到对应的值
for i in alien_0:
    print(alien_0[i])

a = alien_0.keys()
print(type(a))

alien_0 = {'color': 'green', 'points': 5}

# 添加值

alien_0['name'] = 'stan'
alien_0['character'] = 'outgoing'
alien_0['family'] = ['1', '2']

# 删除值

del alien_0['points']

# 输出字典

print(alien_0)
print(alien_0['family'])

for i, j in alien_0.items():
    print("key:",i,"value:",j)

print("*"*11)

# 得到的是键,可以通过键得到对应的值

for i in alien_0:
    print(alien_0[i])

a = alien_0.keys()
print(type(a))

(1)排序

按照键的大小排序

alien_2 = {'color': 'blue', 'points': 11,'a':1}

for c in alien_2:
    print(c,alien_2[c])

# 排序
for c in sorted(alien_2):
    print(c,alien_2[c])

列表嵌套

alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'red', 'points': 6}
alien_2 = {'color': 'blue', 'points': 11}

# 将字典放入列表
li = [alien_0, alien_1, alien_2]
print(li[1])

# 用循环来放入列表,取出前五个
lis = []
for i in range(10):
    lis.append(alien_1)

print(lis[:5])

# 将列表放入字典

pziza = {
    'cust':'thick',
    'topping':['mushroom', 'extra cheese']
}
# 取值
for i in pziza["topping"]:
    print(i)

3.全局变量

main 之中的变量有时被称为全局 变量,因为它们可以在任意函数中访问。和局 部变量在函数结束时就消失不同,全局变量可以在不同函数的调用之间持久存在

全局变量常常用作标志 (flag);它是一种布尔变量,可以标志一个条件是否为真。

比如我们想要通过函数改变一个全局变量时:

been_called = False
def example2():
    # 如果不先声明这个全局变量,则不能修改为True
    global been_called
    been_called = True


example2()
print(been_called)

❌举个错误例子,更新全局变量

count = 0
def example3():
	count = count + 1 

就会报错:

UnboundLocalError: local variable 'count' referenced before assignment

解决方法:

在函数中声明全局变量

count = 0
def example3():
    global count
	count = count + 1 
    print(count)

🚩小结:如果想要给全局变量 重新赋值,则需要声明它


未完待续…

本文章对于初学者也十分友好,也可以用来查漏补缺,是博主自己结合一些书籍和自己的经验写的教程。如果想要完整的md文件和代码(全是我自己总结的哦~)后续还会更新,值得收藏

可以加我qq:2024810652, 当然也可以加我的qq群:785318982,人很多,大佬也多,闲者勿扰。

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弈鸣coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值