当前位置: 主页 > Python语言

python中range函数-python range函数

发布时间:2023-03-11 12:06   浏览次数:次   作者:佚名

原文:

1. 概述

在Python代码中,经常见到函数中有*args和**kwargs写法,它们都起到了可选参数(optional arguments)的作用。那么具体怎么使用呢?且看下文细细分解。

2. *和**

在了解*args和**kwargs的作用之前,首先要理解*和**在Python中的使用。*和**主要有三方面的用途,(一)是对可迭代对象进行拆分,(二)可变变量的赋值,(三)函数的可选参数标志。

2.1 用于对可迭代对象进行拆分

在Python中,一切内置了__iter__方法的对象都是可迭代对象,典型的可迭代对象包括元组(tuple)、列表(list)、集合(set)、字典(dict)等等。这种拆解主要运用在函数的参数语境中,以print函数为例,以下5个表达式是完全等价的:

print("a""b""c")                
print(*("a""b""c"))             # 元组 
print(*["a""b""c"])             # 列表
print(*{"a"1"b"2"c"3})    # 注意:对字典拆解时只拆解key
print(*"abc")                       # 注意:字符串也是可迭代对象

输出结果完全一样(如下)。但是要注意的是,集合不太一样,因为集合是无序的,所以print(*{"a", "b", "c"})的时候"a", "b", "c"可能是乱序的。

a b c
a b c
a b c
a b c
a b c

除了函数参数语境,赋值语境下也可以对可迭代对象进行拆分,如

a = *range(3),
b = *range(3), 3
c = [*range(3)]
d = {*range(3)}
e = {*{'y'1}}     # 只对key进行拆解
f = {**{'y'1}}    # 对key和value都进行了拆解


print(a)  # output: (0,1,2)
print(b)  # output: (0,1,2,3)
print(c)  # output: [0,1,2]
print(d)  # output: {0,1,2}
print(e)  # output: {'y'}
print(f)  # output: {'y':1}

但是这种用法只能在元组、列表、集合和字典内部使用,其他地方就会报错,比如

a = *range(3),   # 这么写默认是在元组内部,即等效于a = (*range(3), )
a = *range(3)    # 这么写就会报错

2.2 可变变量的赋值

如果对于一个可迭代对象l = [1, 2, 3, 4, 5, 6],如果我想把第一个元素赋值给变量a,而把剩下的元素通通赋值给变量b,该怎么写呢?你可能会想这么写

l = [123456]
a = l[0]
b = l[1:]

这么写有两个问题:(一)设想一个更复杂的情况,如果我想把第一个元素赋值给变量a,最后一个元素赋值给c,而把剩下的元素统统赋值给变量b,那么代码将变得又臭又长;(二)这么写对于unsubscriptable的对象是不适用的python中range函数,比如集合。用*可以非常优雅地解决这个问题,如

a, *b, c = {123456}

2.3 函数的可选参数标志

理解了前面两点,这一点其实就是上面两点的综合运用。如果是单星号*标记的就是可选的位置参数(positional arguments)python中range函数,如果是双星号标记的就是可选的关键词参数(keyword arguments),如

def function(a, *args, **kwargs):
    print(a)
    print(args)
    print(kwargs)

function(123, c=4)

输出结果如下

1
(23)
{'c'4}

3. args: positional arguments

args指的是可选的位置参数,这个东西有什么用呢?举个简单的例子我想自定义一个函数求两个元素的和,可以这么写

def my_sum_function(a, b):
    print(a + b)

my_sum_function(12)

可是如果我想求三个元素的和呢,那是不是要这样写?

def my_sum_function(a, b, c):
print(a + b + c)

my_sum_function(123)

你可能已经意识到了,就是这种写函数的思路扩展性非常差,对传入参数的个数有着严格的要求。*args可以解决这一问题,如

def my_sum_function(*args):
    print(sum(args))

# 对于这个函数,不管传入多少个参数都是可以的
my_sum_function(1)
my_sum_function(12)
my_sum_function(123)

4. kwargs: keyword arguments

既然已经有了可选的位置参数(args),还要可选的关键词参数(kwargs)干嘛呢?关键词参数相当于给参数一个关键词,有着特定的用途,关键词对这个特殊用途进行标识。由于需要关键词,因此kwargs的传入函数的类型是字典。

比如我想定义一个函数:这个函数计算传入参数的和,但是如果我传入的参数中包含分母(denominator),就会在这个和的基础上再除以分母。在这种情形下,这个分母(denominator)不一定需要,因此是可选参数。同时,有区别于其他的位置参数,因此需要加一个关键词。这个函数可以这么写

def self_defined_function(*args, **kwargs):
if "denominator" not in kwargs:
print(sum(args))
else:
# 注意:kwargs的类型是字典
denominator = kwargs["denominator"]
print(sum(args) / denominator)

# 没有denominator时,打印几个数的和
self_defined_function(123)
# 有denominator时,先求几个数的和,再除以denominator
self_defined_function(123, denominator=3)

当然,这个函数有更优雅的写法,就是用kwargs.get()或者kwargs.pop(),如

def self_defined_function(*args, **kwargs):
denominator = kwargs.get("denominator"1)
print(sum(args) / denominator)

self_defined_function(123)
self_defined_function(123, denominator=3)

kwargs.get("denominator", 1)会从kwargs这个字典中读取"denominator"这个key对应的值,如果没有这个key,就会返回1。这样写可以避免不断地写if else语句。

kwargs.pop()与kwargs.get()不同的地方在于,kwargs.pop()读取某个key对应的值后,kwargs这个字典中的这个键值对就会被删除。

5. 注意

在Python中默认的函数参数顺序是:必选参数、默认参数、*args和**kwargs。如

def self_defined_function(name, purpose="Demo", *args, **kwargs):
    # name是必选参数
    # purpose是默认参数

    print("Name: ", name)
    print("Purpose: ", purpose)
    denominator = kwargs.pop("denominator"1)
    print(sum(args) / denominator)

# 这里"Demo"不能少
self_defined_function("A self-defined function""Demo"123, denominator=3)

在这种写法中,你会发现"Demo"不能少,如果少了"Demo",purpose就变成了1。同时你又不能下面这样写,因为这样不符合传参的规范

# 不能这样写,这不符合传参的规范
self_defined_function("A self-defined function", purpose="Demo"123, denominator=3)

这样程序会报错。既然无论如何都必须要把"Demo"参数写出来,那么默认参数就失去了意义。因此在Python3中放松了对顺序的限制[2],只要**kwargs放在最后就行,剩下三个(必选参数、默认参数、*args)的顺序不做严格规定,因此上述问题就可以得到解决

def self_defined_function(name, *args, purpose="Demo", **kwargs):
    # name是必选参数
    # purpose是默认参数

    print("Name: ", name)
    print("Purpose: ", purpose)
    denominator = kwargs.pop("denominator"1)
    print(sum(args) / denominator)

# 默认参数purpose终于不需要专门定义了
self_defined_function("A self-defined function"123, denominator=3)

好消息!

小白学视觉知识星球

开始面向外开放啦


python中range函数_python range函数源码_python range函数



下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

python range函数源码_python中range函数_python range函数


python range函数源码_python range函数_python中range函数