2014-02-20 28 views
-2

Python標準庫中哪些類型和類支持數學運算,但不是真正的數字?支持數學運算符的標準python類?

兩個我所知道的是:

  • list一般,特別是字符串,
  • tuples
  • bool值:這是一個讓我吃驚

還有其他的嗎?

注:以我的思維方式,datetime的行爲同樣的數字給我,讓他們確定。

上下文是,我試圖編寫一個允許任意類型插值的函數。

我的第一個想法是:

def weighted_combine(val1, val2, weight): 
    ''' Return the weighted combination of val1 and val2 
     @arg weight : 0 => ignore val2, 1 => ignore val1 
         0.5 => 50/50 mix of val1, val2 
    ''' 
    try: 
     # if I can do math, do it 
     return val1+(val2-val1)*weight 
    except TypeError,e: 
     pass 
    # otherwise pick the predominant value 
    if weight>0.5: 
     return val2 
    else: 
     return val1 

搞清楚,這應該幾乎任何類型的右側上工作。直到我檢查,如果你可以做布爾值(和布爾丘壑numpy的陣列)的數學,所以現在我需要增加明確的類型,這些特殊情況檢查(因爲我想用「挑接近」爲布爾變量的邏輯),所以我需要知道在這種情況下是否還需要考慮其他特殊類型。

示例結果:

In [4]: True+(False-True)*0.2 
Out[4]: 0.8 

In [8]: a=scipy.array([True, False, True]) 

In [9]: a+(a-a)*0.2 
Out[9]: array([ 1., 0., 1.]) 
+0

「布爾值」:這是一個讓我感到驚訝的「?真?布爾語在C語言和其他語言中被視爲int,有很長的歷史。 [documentation](http://docs.python.org/2/library/functions.html#bool)明確指出'bool'是'int'的一個子類。 – Bakuriu

+0

我曾經認爲當真/假分別更改爲「關鍵詞」(或精確的術語),他們會不再是同構的數字,這不是我的風格依賴於C++該功能的一部分。 – Dave

+0

那麼,你*可以*在Python中依賴它。我相信它在文檔中多個地方的陳述的,也是在[PEP 285](http://legacy.python.org/dev/peps/pep-0285/),其中提出了'bool'類型。在某些情況下,使用布爾值作爲整數很有用。 – Bakuriu

回答

1

隨着骯髒的黑客:

>>> [i for i in dir(__builtins__) if hasattr(getattr(__builtins__, i), "__add__")] 
['False', 'True', '__debug__', '__doc__', '__name__', 'bool', 'bytearray', 'bytes', 'complex', 'float', 'int', 'list', 'str', 'tuple'] 

所以:

  • bytearr唉
  • 字節
  • 複雜
  • 浮動
  • INT
  • 列表
  • 海峽
  • 元組

從建宏,但就會有更多的標準l圖書館,我可以想到collections,decimals等等。

1

你可以找到object所有子類,並檢查他們是否有__add__方法。要獲得子類,請使用__subclasses__()方法。這是python3的一個實現。3+:

def find_all_classes(pred, *, start_cls=object, operation=lambda x: x): 
    if pred(start_cls): 
      yield operation(start_cls) 
    for subclass in type.__subclasses__(start_cls): 
     yield from find_all_classes(
      pred, 
      start_cls=subclass, 
      operation=operation, 
     ) 

然而,這可能兩次,如果一個以上的參考被發現計數類,這是可能的,因爲多重繼承等。更準確地執行將是:

def find_all_classes(pred, *, start_cls=object, operation=lambda x: x, found=None): 
    if found is None: 
     found = set() 
    if start_cls in found: 
     return 
    found.add(start_cls) 

    if pred(start_cls): 
      yield operation(start_cls) 
    for subclass in type.__subclasses__(start_cls): 
     yield from find_all_classes(
      pred, 
      start_cls=subclass, 
      operation=operation, 
      found=found, 
     ) 

實例:

In [2]: result = list(find_all_classes(lambda cls: hasattr(cls, '__add__'))) 

In [3]: len(result) 
Out[3]: 232 

In [4]: result[:10] 
Out[4]: 
[builtins.weakcallableproxy, 
builtins.weakproxy, 
builtins.int, 
builtins.bool, 
inspect._ParameterKind, 
builtins.bytearray, 
builtins.bytes, 
multiprocessing.process.AuthenticationString, 
numpy.bytes_, 
builtins.list] 

在新鮮IPython的終端有支持+不同的類運營商。

In [8]: len(list(find_all_classes(lambda cls: hasattr(cls, '__sub__')))) 
Out[8]: 75 

但是隻有75個支持-。差異可能是由於許多允許+的類實際上是序列而不是數值類型,因此它們使用+以某種方式「連接」,但-沒有任何意義。


在你的情況,我不知道是否有任何意義檢查所有這些值,甚至其中一些。您可以嘗試將結果轉換爲原始的dtype,但是這需要特殊外殼numpy的陣列等。

如果您有一些您想要支持的特殊情況,那麼添加它是有意義的,但是有沒有一個簡單的方法來支持用算術運算和產生一個合理的結果任何對象,因爲+-*工作完全不同的類型之間。我只是簡單地把它放在鴨子鍵入,並說這個函數應該用於數字輸入或類型選擇特殊情況的輸入。