Min-max python v3实现
我目前正试图为python中的内置min max函数编写一个等价的代码,我的代码返回了一个非常奇怪的异常,我完全不理解:Min-max python v3实现,python,max,min,minmax,Python,Max,Min,Minmax,我目前正试图为python中的内置min max函数编写一个等价的代码,我的代码返回了一个非常奇怪的异常,我完全不理解: TypeError: 'generator' object is not subscriptable, min, 7, , 9 当我尝试以下方法时: min(abs(i) for i in range(-10, 10)) 这是我的密码: def min(*args, **kwargs): key = kwargs.get("key", None) argv=0 for i
TypeError: 'generator' object is not subscriptable, min, 7, , 9
当我尝试以下方法时:
min(abs(i) for i in range(-10, 10))
这是我的密码:
def min(*args, **kwargs):
key = kwargs.get("key", None)
argv=0
for i in args:
argv+=1
if argv == 1 and (type(args) is list or type(args) is tuple or type(args) is str):
min=args[0][0]
for i in args[0]:
if key != None:
if key(i) < key(min):
min = i
else:
if i < min:
min = i
return min
else:
min=args[0]
for i in args:
if key != None:
if key(i) < key(min):
min = i
else:
if i < min:
min = i
return min
defmin(*args,**kwargs):
key=kwargs.get(“key”,无)
argv=0
对于args中的i:
argv+=1
如果argv==1且(类型(args)为列表或类型(args)为元组或类型(args)为str):
min=args[0][0]
对于args[0]中的i:
如果是钥匙!=无:
如果键(i)<键(min):
min=i
其他:
如果i
根据文档,我应该能够遍历生成器…您遇到的问题是由于
min
有两个函数签名。从其文档字符串:
min(...)
min(iterable[, key=func]) -> value
min(a, b, c, ...[, key=func]) -> value
因此,它将接受单个位置参数(iterable,您需要比较的who's值)或多个位置参数,这些位置参数本身就是值。我认为您需要在功能开始时测试您处于哪种模式。只需执行args=args[0]
即可将单参数版本转换为多参数版本
下面是我实现该函数的尝试key
是一个只包含关键字的参数,因为它出现在*args
之后
def min(*args, key=None): # args is a tuple of the positional arguments initially
if len(args) == 1: # if there's just one, assume it's an iterable of values
args = args[0] # replace args with the iterable
it = iter(args) # get an iterator
try:
min_val = next(it) # take the first value from the iterator
except StopIteration:
raise ValueError("min() called with no values")
if key is None: # separate loops for key=None and otherwise, for efficiency
for val in it: # loop on the iterator, which has already yielded one value
if val < min_val
min_val = val
else:
min_keyval = key(min_val) # initialize the minimum keyval
for val in it:
keyval = key(val)
if keyval < min_keyval: # compare keyvals, rather than regular values
min_val = val
min_keyval = keyval
return min_val
您遇到的问题是由于
min
有两个函数签名。从其文档字符串:
min(...)
min(iterable[, key=func]) -> value
min(a, b, c, ...[, key=func]) -> value
因此,它将接受单个位置参数(iterable,您需要比较的who's值)或多个位置参数,这些位置参数本身就是值。我认为您需要在功能开始时测试您处于哪种模式。只需执行args=args[0]
即可将单参数版本转换为多参数版本
下面是我实现该函数的尝试key
是一个只包含关键字的参数,因为它出现在*args
之后
def min(*args, key=None): # args is a tuple of the positional arguments initially
if len(args) == 1: # if there's just one, assume it's an iterable of values
args = args[0] # replace args with the iterable
it = iter(args) # get an iterator
try:
min_val = next(it) # take the first value from the iterator
except StopIteration:
raise ValueError("min() called with no values")
if key is None: # separate loops for key=None and otherwise, for efficiency
for val in it: # loop on the iterator, which has already yielded one value
if val < min_val
min_val = val
else:
min_keyval = key(min_val) # initialize the minimum keyval
for val in it:
keyval = key(val)
if keyval < min_keyval: # compare keyvals, rather than regular values
min_val = val
min_keyval = keyval
return min_val
以下是我的实现:
def max(*args, **kwargs):
key = kwargs.get("key", lambda x: x)
if len(args) == 1:
args = args[0]
maxi = None
for i in args:
if maxi == None or key(i) > key(maxi):
maxi = i
return maxi
def min(*args, **kwargs):
key = kwargs.get("key", lambda x: x)
if len(args) == 1:
args = args[0]
mini = None
for i in args:
if mini == None or key(i) < key(mini):
mini = i
return mini
def max(*args,**kwargs):
key=kwargs.get(“key”,lambda x:x)
如果len(args)==1:
args=args[0]
最大值=无
对于args中的i:
如果maxi==无或键(i)>键(maxi):
maxi=i
返回最大值
def最小值(*args,**kwargs):
key=kwargs.get(“key”,lambda x:x)
如果len(args)==1:
args=args[0]
迷你=无
对于args中的i:
如果mini==无或键(i)<键(mini):
mini=i
返回迷你
比预览帖子简洁一点。以下是我的实现:
def max(*args, **kwargs):
key = kwargs.get("key", lambda x: x)
if len(args) == 1:
args = args[0]
maxi = None
for i in args:
if maxi == None or key(i) > key(maxi):
maxi = i
return maxi
def min(*args, **kwargs):
key = kwargs.get("key", lambda x: x)
if len(args) == 1:
args = args[0]
mini = None
for i in args:
if mini == None or key(i) < key(mini):
mini = i
return mini
def max(*args,**kwargs):
key=kwargs.get(“key”,lambda x:x)
如果len(args)==1:
args=args[0]
最大值=无
对于args中的i:
如果maxi==无或键(i)>键(maxi):
maxi=i
返回最大值
def最小值(*args,**kwargs):
key=kwargs.get(“key”,lambda x:x)
如果len(args)==1:
args=args[0]
迷你=无
对于args中的i:
如果mini==无或键(i)<键(mini):
mini=i
返回迷你
比预览帖子简洁一点。相关函数有很多共同点。事实上,唯一的区别是比较(
)。鉴于这一事实,我们可以实现查找和元素的泛型函数,它将使用作为参数传递的比较函数。最小值和最大值示例可能如下所示:
def lessThan(val1, val2):
return val1 < val2
def greaterThan(val1, val2):
return val1 > val2
def find(cmp, *args, **kwargs):
if len(args) < 1:
return None
key = kwargs.get("key", lambda x: x)
arguments = list(args[0]) if len(args) == 1 else args
result = arguments[0]
for val in arguments:
if cmp(key(val), key(result)):
result = val
return result
min = lambda *args, **kwargs: find(lessThan, *args, **kwargs)
max = lambda *args, **kwargs: find(greaterThan, *args, **kwargs)
所讨论的功能有很多共同点。事实上,唯一的区别是比较(
)。鉴于这一事实,我们可以实现查找和元素的泛型函数,它将使用作为参数传递的比较函数。最小值和最大值示例可能如下所示:
def lessThan(val1, val2):
return val1 < val2
def greaterThan(val1, val2):
return val1 > val2
def find(cmp, *args, **kwargs):
if len(args) < 1:
return None
key = kwargs.get("key", lambda x: x)
arguments = list(args[0]) if len(args) == 1 else args
result = arguments[0]
for val in arguments:
if cmp(key(val), key(result)):
result = val
return result
min = lambda *args, **kwargs: find(lessThan, *args, **kwargs)
max = lambda *args, **kwargs: find(greaterThan, *args, **kwargs)
您可以在生成器上迭代。您不能执行
生成器[0]
(“不可订阅”)。它抱怨min=args[0][0]
。但是,如果无法从其值中提取默认值,如何将其设置为min?首先将其设置为None
,然后在遍历生成器时检查它是否为None
(这样您就可以将其设置为第一个元素),然后(如果没有元素)。正如您所知,args
将始终是一个元组,因此将始终输入if
块,而永远不会输入else
块。此外,由于if
和else
中都有一个无条件的返回
,因此您的第一个for
循环将永远不会通过第一次迭代。您也可以删除它,并检查argv
。好的,谢谢,我不知道,我将尝试hlt解决方案并更改我的代码,您可以在生成器上迭代。您不能执行生成器[0]
(“不可订阅”)。它抱怨min=args[0][0]
。但是,如果无法从其值中提取默认值,如何将其设置为min?首先将其设置为None
,然后在遍历生成器时检查它是否为None
(这样您就可以将其设置为第一个元素),然后(如果没有元素)。正如您所知,args
将始终是一个元组,因此将始终输入if
块,而永远不会输入else
块。此外,由于if
和else
中都有一个无条件的返回
,因此您的第一个for
循环将永远不会通过第一次迭代。您也可以删除它,并检查argv
。好的,谢谢,我不知道,我将尝试hlt解决方案并更改我的代码,这是一种非常优雅的方式,我必须承认我不会这样想。但我不明白你为什么