web-dev-qa-db-ja.com

Pythonのsum()と非整数値

整数以外の値でsum()を使用する簡単で迅速な方法はありますか?

だから私はそれを次のように使うことができます:

class Foo(object):
    def __init__(self,bar)
        self.bar=bar

mylist=[Foo(3),Foo(34),Foo(63),200]
result=sum(mylist) # result should be 300

__add____int__などをオーバーライドしようとしましたが、まだ解決策が見つかりません

編集:

解決策は、以下を実装することです。

 def __radd__(self, other):
    return other + self.bar

ウィルが彼の投稿で示唆したように。いつものように、すべての道はローマに通じていますが、クラスに__add__が必要ないので、これが最善の解決策だと思います

25
sloth

少し注意が必要です。sum()関数が開始を取得し、次の関数に追加します。

__radd__メソッドを実装する必要があります。

class T:
    def __init__(self,x):
        self.x = x
    def __radd__(self, other):
        return other + self.x

test = (T(1),T(2),T(3),200)
print sum(test)
28
Will

また、___radd___関数を実装する必要がある場合もあります。この関数は、「逆加算」を表し、引数を「順」方向に解決できない場合に呼び出されます。たとえば、_x + y_は可能であればx.__add__(y)として評価されますが、それが存在しない場合はPythonはy.__radd__(x)を試行します。

sum()関数は整数_0_で始まるため、最初に行うことは次のことを評価することです。

_0 + Foo(3)
_

これには、_Foo.__radd___を実装する必要があります。

19
Greg Hewgill

試してみてください:

import operator
result=reduce(operator.add, mylist)

sum()はおそらくより高速に動作しますが、組み込みの数値のみに特化しています。もちろん、Foo()オブジェクトを追加するメソッドを提供する必要があります。完全な例:

class Foo(object):
    def __init__(self, i): self.i = i
    def __add__(self, other):
        if isinstance(other, int):
            return Foo(self.i + other)
        return Foo(self.i + other.i)
    def __radd__(self, other):
        return self.__add__(other)

import operator
mylist = [Foo(42), Foo(36), Foo(12), 177, Foo(11)]
print reduce(operator.add, mylist).i
5
liori

または、何もインポートしたくない場合は、

result = reduce((lambda x,y:x+y), mylist)

もう1つの小さな利点は、Fooオブジェクトの一部として__add__メソッドを宣言する必要がないことです。これが、追加を実行したい唯一の状況である場合です。 (ただし、将来の柔軟性のために__add__を定義しても問題はないでしょう。)

5
Amber

__int__メソッドを使用してから、リスト内の各要素をint関数にマッピングして、値を取得してみてください。

class Foo(object):
    def __init__(self,bar):
        self.bar = bar
    def __int__(self):
        return self.bar

mylist = [Foo(3),Foo(34),Foo(63),200]
result = sum(map(int,mylist))
print(result)
3
Andrew Hare