range()
Pythonで次のリストをどのように作成できますか?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
range()
Pythonで次のリストをどのように作成できますか?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
回答:
reversed()
関数を使用:
reversed(range(10))
それははるかに意味があります。
更新:
(btkが指摘したように)リストにしたい場合:
list(reversed(range(10)))
更新:
range
同じ結果を得るためだけに使用したい場合は、そのすべてのパラメーターを使用できます。range(start, stop, step)
たとえば、リストを生成するに[5,4,3,2,1,0]
は、以下を使用できます。
range(5, -1, -1)
直感的ではないかもしれませんが、コメントが言及するように、これはより効率的であり、逆リストの範囲の正しい使用法です。
range(10)
ませんrange(9)
。また、完全な形式のリスト(スライスなど)が必要な場合は、を実行する必要がありますlist(reversed(range(10)))
。
reversed
、一般的にジェネレータを受け入れませんが、を受け入れますrange
。reversed(range(10000))
リスト全体にメモリを割り当てる必要があるのはなぜですか?効率的な逆反復を可能にrange
する__reversed__
メソッドを実装するオブジェクトを返すことができますか?
「範囲」組み込み関数を使用します。署名はrange(start, stop, step)
です。これにより、から始まり、start
にstop
達した場合に終了する(を除く)までの数値を生成するシーケンスが生成されますstop
。
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
Python 3では、これは非リストrange
オブジェクトを生成します。これは、読み取り専用リストのように効果的に機能します(ただし、特に大きな範囲の場合、メモリの使用量がはるかに少なくなります)。
help(range)
Pythonシェルで実行すると、引数が表示されます。これらは、開始する数、終了する数(排他的)、および実行するステップであるため、9から始まり、-1になるまで1を減算します(その時点で、戻りなしで停止します。これが理由です。範囲は0で終了します)
range(start, stop, step)
-数値から開始し、到達しstart
ない限り結果を生成しstop
、step
毎回移動します。
これまでに収集されたオプションの「効率」に興味がある人のために...
Jaime RGPの答えにより、Jasonのやや「やりがいのある」ソリューションを文字通り自分の提案に従って(コメントを介して)計時した後、コンピューターを再起動するようになりました。好奇心が強いダウンタイムを回避するために、ここに私の結果を示します(最悪のものから)。
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
martineauの答え(拡張スライス構文に精通している場合は読める):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
MichałŠrajerの回答(受け入れられたもの、非常に読みやすい):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
最後のオプションはrange(n-1,-1,-1)
、Val Neekmanによる表記を使用すると覚えやすいです。
reverse
rangeメソッドは逆リストを返す可能性があるため、使用しても意味がありません。n個のアイテムを反復処理しrange(start, stop, step)
ていて、返されたリストの順序を置き換えたい場合は、それを識別してに設定する範囲の3番目のパラメーターを使用する必要があります。他のパラメーターはそれに応じて調整されます。step
-1
-1
(それが以前の値だstop - 1
、stop
と等しかったです0
)。n-1
。したがって、range(n)の逆順での等価は次のようになります。
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
読みやすさはさておき、reversed(range(n))
より速いようですrange(n)[::-1]
。
$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop
誰かが疑問に思っていたなら:)
range(1000000000-1,-1,-1)
か
この質問の要件でlist
は、サイズが10の整数の降順でa が必要です。それでは、Pythonでリストを作成してみましょう。
# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------
# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>
# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
-1
本当に好きです。このパターンこそが維持を容易にしますwrap one's head around this
-今日、本当に効率的でなければならないならrange(n-1, -1, -1)
、逆の順序で範囲をトラバースするときに使用することを学びました。
range()BIF Likeで逆数の印刷を行うことができます、
for number in range ( 10 , 0 , -1 ) :
print ( number )
出力は[10,9,8,7,6,5,4,3,2,1]になります
range()-range(start、end、increment / decrement)ここで、startは包括的で、endは排他的で、incrementは任意の数値で、stepのように動作します
非常によくある質問は、Python 3 range(9, -1, -1)
よりも優れているかどうかreversed(range(10))
です。イテレータを使用して他の言語で作業したことがある人は、reversed()がすべての値をキャッシュしてから逆の順序で戻る必要があるとすぐに思う傾向があります。ことはreversed()
、オブジェクトが単なるイテレータである場合、Pythonの演算子は機能しないということです。reverse()が機能するためには、オブジェクトが2つ以下のいずれかでなければなりません。
len()
と整数インデックスのいずれか[]
__reversed__()
メソッドを実装します。上記のいずれもないオブジェクトでreverse()を使用しようとすると、次のようになります。
>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible
つまり、Python reversed()
はオブジェクトのような配列のみを対象としているため、順方向反復と同じパフォーマンスが得られるはずです。
しかし、どうrange()
ですか?それは発電機ではありませんか?Python 3ではジェネレーターですが、上記の両方を実装するクラスにラップされています。したがってrange(100000)
、メモリを大量に消費することはありませんが、効率的なインデックス作成と逆転をサポートしています。
つまり、要約すると、reversed(range(10))
パフォーマンスに影響を与えることなく使用できます。
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))
エラーが起こりにくいのかを示しています。アシノックスを攻撃しません。正直なところ。
必ずしもrange関数を使用する必要はありません。list[::-1]を実行するだけで、追加を使用せずにリストを逆順ですばやく返すことができます。
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
正しい形です。使用する場合
reversed(range(10))
あなたは0ケースを取得しません。たとえば、10はマジックナンバーではなく、逆方向から検索を開始するために使用している変数だとします。nのケースが0の場合、reversed(range(0))は実行されません。これは、偶然にゼロのインデックスに単一のオブジェクトがある場合は間違っています。
タイトルに記載されているように、既存のリストを逆順でトラバースする一般的なケースには、そのようなトラバーサルのインデックスを生成するだけでなく、タイトルに記載されているように、多くの人がもっと興味があるかもしれないと思いました。
この場合でも正しい答えはすべて完全に良好ですが、ウルフの答えで行われたパフォーマンス比較はインデックスの生成のみを目的としていることを指摘しておきます。そのため、既存のリストを逆順でトラバースするための同様のベンチマークを作成しました。
TL; DR a[::-1]
が最速です。
前提条件:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
ご覧のとおり、この場合、明示的にインデックスを生成する必要はないため、最速の方法は余分なアクションを少なくする方法です。
注:便利な「マジックコマンド」を備えたJupyterLabでテストしました%timeit
。それはtimeit.timeit
フードの下で標準を使用します。Python 3.7.3でテスト済み