2014-01-06 13 views
14

absはnumpy配列では動作しますが、リストには作用しません。何故ですか?absのような組み込み関数がnumpy配列で動作するのはなぜですか?

import numpy as np 

abs(np.array((1,-2))) 
array([1, 2]) 

abs([1,-1]) 
TypeError: bad operand type for abs(): 'list' 

sumなどの組み込み関数もnumpy配列で動作します。 numpyの配列が__getitem__をサポートしているからでしょうか?しかし、absの場合、それは__getitem__に依存していればそれもリストのために働くはずですが、そうではありません。

答えて

19

numpy.ndarray__abs__(self)メソッドを実装しているからです。あなた自身のクラスに提供するだけで、abs()は魔法のように動作します。非組み込み型の場合、この機能を事後的に提供することもできます。例えば。

class A: 
    "A class without __abs__ defined" 
    def __init__(self, v): 
     self.v = v 

def A_abs(a): 
    "An 'extension' method that will be added to `A`" 
    return abs(a.v) 

# Make abs() work with an instance of A 
A.__abs__ = A_abs 

しかし、これは、このようなlistdictなどのビルトインタイプのために動作しません。

4

abs機能は__abs__の方法を探します。

numpyのように、あなたのクラスに__abs__メソッドを実装して、absが動作するようにすることもできます。そのようなリストまたはnumpyのアレイなどイテラブルに

すなわち

class A(object): 
    def __abs__(self): 
     return 8 

>>> a= A() 
>>> abs(a) 
8 
>>> 
2

sum作品。

な数字やnumpy.arraysなど__abs__方法を定義する値にabs作品、:

>>> x = -1 
>>> x.__abs__() 
1 

>>> class A(object): 
...  def __abs__(self): 
...   return 12 
>>> a = A() 
>>> abs(a) 
12 

listあなたは、それぞれ(map(abs, [1, -1])[abs(x) for x in [1,-1]]をマップやリスト内包表記を使用することができますが、sは、このメソッドを定義しないでください)あなたが必要とするもののために。あなたが過剰殺到が好きなら、リストをサブクラス化しnumpyのような形に定義することができます__abs__(ただし、一般的には理解が好ましい)

関連する問題