c_ratings_percentages = make_percentages( content_ratings)
print(c_ratings_percentages)
print(content_ratings)
{'4+': 61.595109073224954, '9+': 13.714047519799916, '12+': 16.04835348061692, '17+': 8.642489926358204}
{'4+': 61.595109073224954, '9+': 13.714047519799916, '12+': 16.04835348061692, '17+': 8.642489926358204}
正如我们在列表中看到的,我们的全局content_ratings变量已经更改,尽管它只是在我们创建的make_percentages()函数中进行了修改。
这里到底发生了什么?我们遇到了可变和不可变数据类型之间的差异。
可变和不可变的数据类型
在Python中,数据类型可以是可变的(可更改的),也可以是不可变的(不可更改的)。虽然我们在介绍Python时使用的大多数数据类型都是不可变的(包括整数、浮点数、字符串、布尔值和元组),但是列表和字典是可变的。这意味着全局列表或字典即使在函数内部使用时也可以更改,就像我们在上面的示例中看到的那样。
要理解可变(可更改)和不可变(不可更改)之间的区别,了解Python如何处理这些变量是很有帮助的。
让我们从考虑一个简单的变量赋值开始:
a = 5
变量名a的作用类似于一个指向5的指针,它可以帮助我们随时检索5。
5是一个整数,整数是不可变的数据类型。如果数据类型是不可变的,这意味着一旦创建,就不能更新它。如果我们执行a += 1,我们实际上并没有更新5到6。在下面的动画中,我们可以看到这一点:
a 初始指向 5.
执行a += 1 后, 将指针从 5指向 6, 它并没有实际改变 5.
可变数据类型(如列表和字典)的行为有所不同。它们可以更新。举个例子,我们来创建一个非常简单的列表:
list_1 = [1,2]
如果我们在列表末尾添加一个3,我们不是简单地将list_1指向另一个列表,而是直接更新现有列表:
即使我们创建多个列表变量,只要它们指向同一个列表,当列表被更改时,它们都会被更新,如下面的代码所示:
list_1 = [1,2]
list_2 = list_1
list_1.append(3)
print(list_1)
print(list_2)
[1, 2, 3]
[1, 2, 3]
下面是上面代码中实际发生的动态可视化:
这就解释了为什么我们之前在试验列表和字典时我们的全局变量被改变了。因为列表和字典是可变的,所以更改它们(即使是在函数中)也会更改列表或字典本身,这与不可变数据类型不同。
保持可变数据类型不变
一般来说,我们不希望函数更改全局变量,即使它们包含列表或字典之类的可变数据类型。这是因为在更复杂的分析和程序中,我们可能会经常使用许多不同的函数。如果所有函数都更改它们正在调用的列表和字典,那么要跟踪什么在更改什么就会变得非常困难。
幸运的是,有一种简单的方法可以绕过这个问题:我们可以使用内建的Python方法.copy()复制列表或字典。
如果你还没有学习过方法,请不要担心。它们包含在我们的中级Python课程中,但是在本教程中,你只需要知道.copy()的工作原理类似于.append():
list.append()
list.copy()
让我们再看一下我们为列表写的函数,对它进行更新,这样函数内部执行的操作就不会更改initial_list。我们只需要将传递给函数的参数从initial_list更改为initial_list.copy()
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
initial_list=[1,2,3]
def duplicate_last(a_list):
last_element = a_list[-1]
a_list.append(last_element)
return a_list
new_list = duplicate_last(a_list = initial_list.copy())
print(new_list)
print(initial_list)
[1, 2, 3, 3]
[1, 2, 3]
正如我们所看到的,这已经解决了我们的问题。原因如下:使用.copy()创建一个列表的独立副本,这样a_list就不会指向initial_list本身,而是指向一个以initial_list副本开始的新列表。在此之后对a_list所做的任何更改都将只对该独立列表生效,而不是initial_list本身,因此initial_list的全局值将保持不变。
不过,这个解决方案仍然不完美,因为每次向函数传递参数时都必须记得添加.copy(),否则可能会意外更改initial_list的全局值。如果我们不想操心这个,我们可以在函数内部创建列表拷贝:
initial_list = [1,2,3]
def duplicate_last(a_list):
copy_list = a_list.copy()
last_element = copy_list[-1]
copy_list.append(last_element)
return copy_list
new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
[1, 2, 3, 3]
[1, 2, 3]
使用这种方法,我们可以安全地将一个可变的全局变量(如initial_list)传递给我们的函数,全局值不会被改变,因为函数本身会复制一个副本,然后对该副本执行操作。
.copy()方法也适用于字典。与列表一样,我们可以简单地将.copy()添加到传递给函数的参数中,创建一个用于函数的拷贝,而不会改变原始变量:
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
content_ratings = {'4+':4433,'9+': 987,'12+':1155,'17+': 622}
def make_percentages(a_dictionary):
total = 0
for key in a_dictionary:
count = a_dictionary[key]
total += count
for key in a_dictionary :
a_dictionary[key] = (a_dictionary [key]/ total)*100
return a_dictionary
c_ratings_percentages = make_percentages(content_ratings.copy())
print(c_ratings_percentages)
print(content_ratings)
{'4+': 61.595109073224954, '9+': 13.714047519799916, '12+': 16.04835348061692, '17+': 8.642489926358204}
{'4+': 4433, '9+': 987, '12+': 1155, '17+': 622}
但是,再次说明,使用这种方法意味着在每次将字典传递给make_percentages()函数时,都要记得添加.copy()。如果我们要频繁地使用这个函数,最好在函数内部实现复制,这样我们就不需要记住了。
下面,我们将在函数内部使用.copy()。这样,就可以确保我们在将全局变量作为参数传递给函数时不会被更改,而且我们也不需要记得为传递的每个参数添加.copy()。
content_ratings = {'4+': 4433,'9+': 987,'12+':1155,'17+':622}
def make_percentages(a_dictionary):
copy_dict = a_dictionary.copy()
total = 0
for key in a_dictionary :
count = a_dictionary[key]
total +=count
for key in copy_dict:
copy_dict[key] = (copy_dict[key] / total)*100
return copy_dict
c_ratings_percentages = make_percentages(content_ratings)
print(c_ratings_percentages)
print(content_ratings)
{'4+': 61.595109073224954, '9+': 13.714047519799916, '12+': 16.04835348061692, '17+': 8.642489926358204}
{'4+': 4433, '9+': 987, '12+': 1155, '17+': 622}
正如我们所看到的,修改我们的函数来创建字典的副本,然后只在副本中将计数更改为百分比,这样我们就可以在不更改content_ratings的情况下执行我们想要的操作。
在本教程中,我们研究了可变数据类型(可以更改)和不可变数据类型(不能更改)之间的区别。我们学习了如何使用.copy()方法复制列表和字典等可变数据类型,这样我们就可以在不更改其全局值的情况下在函数中使用它们。
结尾给大家推荐一个非常好的学习教程,希望对你学习Python有帮助!
Python基础入门教程推荐
Python爬虫案例教程推荐
目录函数内部对全局变量的修改情况验证方案结果证明如何在函数内部修改全局列表变量举个简单的栗子结果证明
在python中,对于全局数字变量、字符串变量、列表变量,函数内部只能调用,却无法改变其值;但是,对于字典变量,函数内部是可以改变全局字典变量的值的!
函数内部对全局变量的修改情况
# 全局变量
x = 50
str = 'str'
dt = {'1': 'one'}
li = []
# 自定义函数
def func(x, str, dt, li):
print('局部变量x={},
我们在下面的代码总
中定义了一个edit
全局变量,如果想要在一个
函数的内部去
修改这个
全局变量,就要在这个变量前面加上global关键字
#代码如下:
edit='数据结构-人工智能'
def editGlobal():
global edit
edit = '
python'
editGlobal()
print(edit)
#运行结果:
python
最近有一个需要,是一个变量的内容需要从文件中读取,但是读取完后不能修改,读取文件(比较复杂)写了一段函数表示,这样就产生了一个问题,数据生成后希望不能被其他应用所改变(即作为常量使用),查询资料后大多很模糊而且内容一样,经过自己实验发现可以进行如下操作:在函数外进行变量声明,只需在要改变的函数内(textC)重新使用global声明,其余使用的函数直接读变量(textB)即可:
a = [2] #函数外声明一个变量
def textA():
a = [1] #函数内直接修改
增加字典元素的方法
list['key'] = vaule
这种方法是通过字典的kye给字典添加元素,如果字典里已存在该key的值,则会覆盖,如果不存在,则会添加,如下如:
dic = {'name':'fuyong','age':29,'job':'none'}
dic['addr'] = 'henan'
print(di...
1、python 全局变量在函数中使用时,在函数中给全局变量重新赋值,是不会改变全局变量的值
2、python 全局变量在函数中使用时,在函数中在全局变量前添加global关键字,可以改变全局变量的值
python菜鸟笔记(一)......
腾讯校招官网显示,2022届腾讯校招开放技术、产品、设计等岗位共计 78 个,且以IT岗为主。
另据各大招聘平台统计数据,腾讯2022届研发岗应届生基础月薪在1.7万-2.3万之间,签字费(针对优秀人才的额外奖励)3万,股票依据不同等级从6万到20万不等,就算是最低等级的“白菜包”,年薪总包也远超40万元。
作为一个代码打工仔,对于绝大部分程序员来说,想要成为牛