質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2898閲覧

python3 abs関数もどき作りました。どうでしょうか?

sasuke_killer

総合スコア42

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/07/28 05:51

編集2018/07/28 06:29

abs関数もどきを作りました。

Python3
abs関数と言えば皆さんご存知、絶対数を返す関数です。
初心者の僕でも作れそうな関数だと思ったので作ってみました。
下にコードを載せます。改善点等ありましたらご回答ください!

Python3

1def abs_made(kazu) 2 if kazu<0: 3 X=kazu*-1 4 else: 5 X=kazu 6 return X 7 8print(abs_made(-3))

あ、kazuが数字じゃなかったらエラーメッセージを出す、みたいなコードが書けるのであればヒントを教えていただきたいです。

追記
「こんな書き方もあるよ」って人も回答頂けると有難いです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

関数を定義するだけならラムダ式でもいいかもしれませんね。

Python

1abs_made = lambda x : x if x > 0 else -x

補足

Pythonのabsは絶対値を計算するまえに対象のオブジェクトが持っている__abs__メソッドがあるかを確認しに行きます。numpyの行列を考えるとこのままじゃまずいですし。

import numpy as np mat = np.array([-1, 1]) print(abs(mat)) # ok print(mat.__abs__()) # abs(mat)は実際にはこう動く print(abs_made(mat)) # fail




__abs__の話はクラスを知らないと難しいので、興味がない限りスルーしてください。と断った上で続けます。

__abs__は主にbuilt-in関数のabsによって呼び出される(オブジェクト固有の)メソッドです。numpy.ndarrayという行列の型の場合だと、np.absoluteと同じです。
[https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.absolute.html]
(https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.absolute.html)

疑似コードだとこういう順序です。

Python

1def myabs(x): 2 try: 3 # 4 print("試しにx.__abs__()を呼んでみます") 5 return x.__abs__() 6 except AttributeError: 7 # Xが__abs__を実装していない場合 8 print("x.__abs__()なんてありませんでしたorz") 9 return x if x > 0 else -x

自前でx__abs__を実装したクラスの例は次の通りです。

Python

1class MyClass: 2 def __init__(self, x): 3 self.x = x 4 def __abs__(self): 5 # absに呼び出してもらうための関数 6 # 試しに違う絶対値を実装してみる 7 print(" MyClassの__abs__だよ") 8 return (self.x ** 2) ** (1/2) 9 10A = MyClass(-2) 11print(myabs(A)) # 自作のabs 12print(abs(A)) # Python のbuilt-inのabs

こんな仕組みが用意されている理由の一つとして考えられ得るのは、数学の絶対値absにいろんな定義があるためです。一例を上げると、質問の中にある絶対値の定義は複素数の絶対値の定義と異なります。そうすると、実数なら・・・複素数なら・・・と様々な定義をabs関数に埋め込まないと行けなくなってしまい、とても複雑な関数になってしまいかねません。それを避けるための仕組みなのですが、逆に自分でクラスを作らない限りはこの仕組を意識することはないと思います。

投稿2018/07/28 07:15

編集2018/07/28 08:28
tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2018/07/28 07:27

PEP8違反をしてまでラムダ式を使うメリットも無いような...
sasuke_killer

2018/07/28 07:35

_abs_メソッドとはどのようなものなのでしょうか…?
guest

0

"python abs impliments" で gooogle 検索してみるとよいです。

  • How does Python implement absolute value?

https://www.quora.com/How-does-Python-implement-absolute-value

  • Why doesn't Python have a sign function?

https://stackoverflow.com/questions/1986152/

  • abs() in Python

https://www.geeksforgeeks.org/abs-in-python/

上の一番目のページを参考にこんなコードをかいてみました。
xxx.rb

ruby

1import math 2 3def simple_abs(num): 4 return -num if num < 0 else num 5 6def my_abs(num): 7 return -num if math.copysign(1, num) < 0 else num 8 9x = -0.0 10print("abs:", abs(x)) 11print("simple_abs:", simple_abs(x)) 12print("my_abs:" , my_abs(x)) 13 14`` 15実行結果 16![イメージ説明](48b671dbd1e959da2b2d8afba33d0eba.png)

投稿2018/07/28 07:16

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2018/07/28 08:04

copysignを使うなら return math.copysign(1, num) * num で充分では。
guest

0

ベストアンサー

私が書くならこんなかんじですかね。

Python

1def my_abs(arg): 2 if arg < 0: 3 return -arg 4 5 return arg

あるいは条件演算子を使います。

Python

1def my_abs(arg): 2 return -arg if arg < 0 else arg

ネタ。真似しちゃダメです。

Python

1def my_abs(arg): 2 return [ 3 lambda a: a, 4 lambda a: -a 5 ][arg < 0](arg)

kazuが数字じゃなかったらエラーメッセージを出す

型を調べて例外を投げれば良いです。
が、Pythonの性格にあまりそぐわないような気もします。

型ヒントを付けておけば、静的解析で警告を出すことは可能です。

投稿2018/07/28 06:00

編集2018/07/28 06:34
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sasuke_killer

2018/07/28 06:04

なるほど…Xに代入するだけ無駄でしたねw ありがとうございます!
LouiS0616

2018/07/28 06:07

returnを末尾にまとめた方が見やすいという意見もあるので、一概にXが無駄と言えるわけではないです。 個人的には精神的スタックが減るぶん、早々にreturnする方法が好みですが。
sasuke_killer

2018/07/28 06:08

ん?argが0より小さかったら、-argとargの2つの数が表示される気がするのですが…
LouiS0616

2018/07/28 06:14

returnされたら関数内のそれ以降の文は実行されないです。 もちろんelseを用いても意味的には同じです。これも好みに依ります。
sasuke_killer

2018/07/28 06:16

そうなんですね! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問