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

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

新規登録して質問してみよう
ただいま回答率
85.35%
オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Python

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

Q&A

解決済

3回答

634閲覧

Python: rangeインスタンスにおける「値を取得する」実体はなんでしょうか?

FugahogeDS

総合スコア23

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Python

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

0グッド

0クリップ

投稿2021/05/02 05:24

Pythonにおける range について教えてください。
使うことで範囲を取得できるオブジェクトを返してくれますが、 for などで評価するとひとつ値をくれるということは一応理解してます。

for などのループ構文を使わずに、直接値をひとつずつ取ってこれるメソッドがわからないので、ご存じの方がいたら教えていただきたいという話です。

python

1for i in range(10): # 0, 1, 2 ... ,8, 9 2 print(i) 3 4# 実行すると0〜9が出力される

いわゆるイテレータであることも把握してますが、for文ではrangeのインスタンスに対して、実際に「値をくれ」と呼び出しているメソッドはなんなのでしょうか。
これがわかれば、forなどを使わずに任意タイミングで「その時もらうべき値」がもらえるのではと調べているのですが発見できずにいます。

python

1>>> r = range(5) 2>>> dir(r) 3['__bool__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop'] 4>>> r.なんとか() # 値を取得できるメソッド 51 <- この値を任意タイミングで取得したい 6>>> r.なんとか() # 値を取得できるメソッド 72 8...

という具合に、任意タイミングで値を取得できないかという話になります。

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

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

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

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

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

tetsunosuke

2021/05/02 05:34

ちょっと意図と外れてるかもしれませんがこういうことですか? >>> it = iter(r) >>> next(it) 1 >>> next(it) 2 >>> next(it)
FugahogeDS

2021/05/02 05:40

あー、またpythonの罠にひっかかってもうた。 `next()`で取得できるのですか。ありがとうございます。 では、`next(it)`はitのナニを呼び出しているのでしょう、というのが知りたいことだったりします。
tetsunosuke

2021/05/02 05:41

it.__next__() と同じです で答えになるでしょうか?
FugahogeDS

2021/05/02 05:42

わたしもそう思ったのですが、 __next__()は無いと出てしまいます。 >>> r = range(5) >>> r.__next__() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'range' object has no attribute '__next__'
tetsunosuke

2021/05/02 05:44 編集

あ、いえ 先に it = iter(r) しているわけなので。 (iter(r) は、 r.__iter__() と同じではありますが あ、そういう意味では元質問の > いわゆるイテレータであることも把握してますが rangeはイテレータではなくシーケンス。そこからイテレータとして取り出したものにnext()が使えるということです
FugahogeDS

2021/05/02 05:43

すみません、iter(r)してからなのですね。理解できました。
FugahogeDS

2021/05/02 05:44

一応自己解決したので書き換えていきます。 ありがとうございました!
guest

回答3

0

ベストアンサー

まず使う必要はないと思いますが、やろうと思えばrangeオブジェクトをイテレータオブジェクトにしてnext()で呼び出せばできます。
forループはよしなにやってくれるので、意識しなくて良いのですが、StopIteration が raiseされたら終了です。

python

1>>> r = range(3) 2>>> ir = iter(r) 3>>> next(ir) 40 5>>> next(ir) 61 7>>> next(ir) 82 9>>> next(ir) 10Traceback (most recent call last): 11 File "<stdin>", line 1, in <module> 12StopIteration

投稿2021/05/02 05:47

hide5stm

総合スコア426

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

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

FugahogeDS

2021/05/02 05:56

range()が直接イテレーションではない(あくまで範囲を示す)というところに気付けませんでした…ありがとうございます。
hide5stm

2021/05/02 07:22

確かにrubyの方がオブジェクト指向的に直感的なのはありますね。 pythonは、len()やnext(), all(), any() など多相に使えて便利な関数はあるのですが、調べにくいですよね
guest

0

rangeはイテレータではなくiterableなので、いったんイテレータを取り出す必要がある。

メソッドで、ということなら、イテレータを__iter__で取り出して、__next__を繰り返し呼べばよい。
末尾まで来たらStopIteration例外が発生する。

python

1>>> r = range(5) 2>>> i = r.__iter__() 3>>> i.__next__() 40 5>>> i.__next__() 61 7...

ただ、普通は、組み込み関数iternextを使う。

python

1>>> r = range(5) 2>>> i = iter(r) 3>>> next(i) 40 5>>> next(i) 61 7...

投稿2021/05/02 05:46

actorbug

総合スコア2431

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

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

0

tetsunosukeさんありがとうございます! 本当はtetsunosuke様をベストアンサー設定にしたいですが、もしかしてこちらでは設定できない?

一度iter()でイテレーション可能なものに変換することで、イテレーションからひとつ抜き出す __next__()next(x) にて行えることがわかりました。

iter()はイテレーション可能と思われるなら他のモノでも変換してくれるようで、少なくともリストは変換できました。

python

1>>> x = iter([1,3,5]) 2>>> next(x) 31 4>>> next(x) 53 6>>> next(x) 75 8>>> next(x) 9Traceback (most recent call last): 10 File "<stdin>", line 1, in <module> 11StopIteration

これでひとつ片付いたのですが、あとはiterはナニを使ってrangeオブジェクトから「次の値」を抜き出してるか、ですね。
というか、直接rangeオブジェクトがイテレーションしちゃえば良いのに感。
そういう意味では本当rubyが驚きが少ない

ruby

1irb(main):005:0> x = 1.upto(3) 2=> #<Enumerator: ...> 3irb(main):006:0> x.next 4=> 1 5irb(main):007:0> x.next 6=> 2 7irb(main):008:0> x.next 8=> 3 9irb(main):009:0> x.next 10(irb):9:in `next': iteration reached an end (StopIteration) 11 from (irb):9:in `<main>' 12 from /usr/local/Cellar/ruby/3.0.1/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `<top (required)>' 13 from /usr/local/opt/ruby/bin/irb:23:in `load' 14 from /usr/local/opt/ruby/bin/irb:23:in `<main>'

投稿2021/05/02 05:51

編集2021/05/02 05:54
FugahogeDS

総合スコア23

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問