- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用一个 Python 对象,它实现了 __add__
,但没有子类化 int
。 MyObj1 + MyObj2
工作正常,但是 sum([MyObj1, MyObj2])
导致了 TypeError
,因为 sum()
首先尝试 0 + MyObj
。为了使用sum()
,我的对象需要__radd__
来处理MyObj + 0
或者我需要提供一个空对象作为 start
参数。所讨论的对象并非设计为空。
在任何人问之前,该对象既不是列表也不是字符串,因此使用 join() 或 itertools 无济于事。
编辑细节:该模块有一个 SimpleLocation 和一个 CompoundLocation。我将 Location 缩写为 Loc。 SimpleLoc
包含一个右开区间,即 [start, end)。添加 SimpleLoc
会产生一个 CompoundLoc
,其中包含一个区间列表,例如[[3, 6), [10, 13)]
。最终用途包括遍历联合,例如[3, 4, 5, 10, 11, 12]
,检查长度和成员资格。
数字可以相对较大(例如,小于 2^32,但通常为 2^20)。间隔可能不会很长(100-2000,但可能更长)。当前,仅存储端点。我现在正在尝试对 set
进行子类化,以便将位置构造为 set(xrange(start, end))
。但是,添加集合会让 Python(和数学家)适应。
我看过的问题:
我正在考虑两种解决方案。一种是避免使用 sum()
并使用此 comment 中提供的循环.我不明白为什么 sum()
首先将 iterable 的第 0 项添加到 0 而不是添加第 0 项和第 1 项(就像链接注释中的循环);我希望有一个神秘的整数优化原因。
我的另一个解决方案如下;虽然我不喜欢硬编码的零检查,但这是我能够使 sum()
工作的唯一方法。
# ...
def __radd__(self, other):
# This allows sum() to work (the default start value is zero)
if other == 0:
return self
return self.__add__(other)
总而言之,是否有另一种方法可以对既不能与整数相加也不能为空的对象使用sum()
?
最佳答案
代替 sum
,使用:
import operator
from functools import reduce
reduce(operator.add, seq)
在 Python 2 中,reduce
是内置的,因此看起来像这样:
import operator
reduce(operator.add, seq)
Reduce 通常比 sum 更灵活 - 您可以提供任何二进制函数,而不仅仅是 add
,并且您可以可选地提供一个初始元素,同时 sum
总是使用一个。
另请注意:(警告:前面有数学问题)
从代数的角度来看,为没有中性元素的对象提供对 add
的支持有点尴尬。
请注意所有:
与加法一起形成一个Monoid - 即它们具有关联性并具有某种中性元素。
如果您的操作不是关联的并且没有中性元素,那么它就不会“类似于”加法。因此,不要指望它能与 一起很好地工作求和
。
在这种情况下,使用函数或方法而不是运算符可能会更好。这可能不那么令人困惑,因为您的类的用户看到它支持 +
,可能会期望它以幺半群的方式运行(就像加法通常那样)。
感谢您的扩展,我现在将引用您的特定模块:
这里有2个概念:
添加简单位置确实有意义,但它们不会形成幺半群,因为它们的添加不满足闭包的基本属性 - 两个 SimpleLoc 的总和不是 SimpleLoc。通常,它是一个 CompoundLoc。
OTOH,在我看来,带有加法的 CompoundLocs 就像一个幺半群(一个可交换的幺半群,而我们正在讨论它):它们的总和也是一个 CompoundLoc,它们的加法是结合的、交换的和中性元素是包含零个 SimpleLoc 的空 CompoundLoc。
如果你同意我的观点(并且以上符合你的实现),那么你将能够使用 sum
如下:
sum( [SimpleLoc1, SimpleLoc2, SimpleLoc3], start=ComplexLoc() )
的确,这个appears to work .
I am now tentatively thinking of attempting to subclass set such that the location is constructed as set(xrange(start, end)). However, adding sets will give Python (and mathematicians) fits.
好吧,位置是一些数字集,所以在它们之上抛出一个类似集合的接口(interface)是有意义的(所以 __contains__
, __iter__
, __len__
,也许 __or__
作为 +
的别名,__and__
作为产品等)。
至于从xrange
构造,你真的需要吗?如果您知道您正在存储间隔集,那么您可能会通过坚持 [start, end)
对的表示来节省空间。您可以引入一个实用方法,该方法采用任意整数序列并将其转换为最佳 SimpleLoc
或 CompoundLoc
(如果您觉得它会有所帮助)。
关于python - 避免 Python sum 默认启动 arg 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11624955/
我有这个代码。为了让它工作,我必须使用 Args&&... 而不是 Args... 或 Args&... 我注意到 args 从 & 转换为 const& 或 && 转换为 &。 Args...Arg
当我定义类时,我总是去 Class A(object): def __init__(self, arg): self.arg = arg def print_arg(s
假设我想定义两个 {Type} 类的变量。构造函数采用 1 个参数。下面两种方式是否完全等价(编译成相同的目标代码)? Type a(arg), b(arg); 和 Type a(arg); Type
(旁白:我是一名 Perl 程序员,正如您所知,这是我的第一个重要的 Java 程序。简单的术语将不胜感激。) 我有以下启动器作为编码工作: import java.lang.reflect.*; i
Math.nextUp(arg) 始终与 arg + Math.ulp(arg) 相同,还是我遗漏了什么? System.out.println( 0.5 + Math.ulp(0.5));
今天我在学习完美转发,我创建了这个代码示例 #include #include template auto toStdFun(Function&& fun, Args&&...ar
我想知道你会选择哪个选项? putStrLn (show randomNum) putStrLn $ show randomNum (putStrLn . show) randomNum 所有选项在语
我试图在 visual studio 2012 中编译一个库,它最初是用 c++ 为 visual studio 2015 编写的。我有一个错误说 'class' missing tag。 错误消息的
我在下面的代码中遇到了运行时异常ArrayIndexOutOfBoundException,行中: if ( args[0].equals("t") || args[0].equals("time")
我有以下代码 import React, { Component } from "react"; import { Accounts } from "meteor/accounts-base"; ex
这个问题已经有答案了: Difference between Arrays and 3 dots (Varargs) in java (3 个回答) 已关闭 5 年前。 受学校线性代数 I 和 II
所以我定义了一个函数: def getDistnace(self, strings, parentD, nodeName, nodeDistance): 我用它来调用: Node.getDistnac
这个问题在这里已经有了答案: subprocess.call() arguments ignored when using shell=True w/ list [duplicate] (2 个答案
我想将参数传递给 java 应用程序,但喜欢 linux 应用程序风格。 java 中的main 方法对所有参数使用一个String 数组。在 Linux 中,大多数应用程序接受如下参数:ls -l
这是我的代码片段 #include void change(int a[]){ printf("%p\n",&a); } int main(){
我需要使用 python 3.6 subprocess.run() 函数发出以下命令: gsettings set org.gnome.shell enabled-extensions "['appl
这两个函数是否有任何有意义的不同?有什么理由通常更喜欢一个而不是另一个吗? void foo(auto x, auto &... y) { /* ... */ } template void foo(
例如: def m(arg, ...args) { println "arg: $arg" println "args: $args" } m('arg', k:'v') 输出: ar
我对 Java 还很陌生。目前正在尝试将 args[] 中给出的文件名传递给此 FileReader,但当我编译时,它说找不到指定的文件。如果我对文件名进行硬编码,它就可以正常工作。这应该如何运作?
为什么这是一个语法错误??做这件事的合适方法是什么? >>> def f(*args, option=None): File "", line 1 def f(*args, option=
我是一名优秀的程序员,十分优秀!