range()を使用してリストを逆順に印刷しますか?


364

range()Pythonで次のリストをどのように作成できますか?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

[* range(9、-1、-1)]はどうですか?超パイソン!
onofricamila

回答:


561

reversed()関数を使用:

reversed(range(10))

それははるかに意味があります。

更新:

(btkが指摘したように)リストにしたい場合:

list(reversed(range(10)))

更新:

range同じ結果を得るためだけに使用したい場合は、そのすべてのパラメーターを使用できます。range(start, stop, step)

たとえば、リストを生成するに[5,4,3,2,1,0]は、以下を使用できます。

range(5, -1, -1)

直感的ではないかもしれませんが、コメントが言及するように、これはより効率的であり、逆リストの範囲の正しい使用法です。


13
「効率的」ではありませんが。また、スライス操作を実行することはできません。
Jakob Bowyer

6
この答えは非常に明確で理解しやすいですが、そうである必要はありrange(10)ませんrange(9)。また、完全な形式のリスト(スライスなど)が必要な場合は、を実行する必要がありますlist(reversed(range(10)))
John Y

5
これはイテレータを生成し、OPはリストの形式で結果を要求しました。
btk 2014

6
Pythonジェネレーターで「リバース」を使用する(Python 3の範囲の組み込みについて話していると仮定した場合)は、概念的には間違っており、高水準言語でプログラミングするときにメモリ/処理の複雑さを考慮しないという間違った習慣を教えます。
thedk 2015年

7
Python3ではreversed、一般的にジェネレータを受け入れませんが、を受け入れますrangereversed(range(10000))リスト全体にメモリを割り当てる必要があるのはなぜですか?効率的な逆反復を可能にrangeする__reversed__メソッドを実装するオブジェクトを返すことができますか?
avmohan 2017

312

「範囲」組み込み関数を使用します。署名はrange(start, stop, step)です。これにより、から始まり、startstop達した場合に終了する(を除く)までの数値を生成するシーケンスが生成されます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オブジェクトを生成します。これは、読み取り専用リストのように効果的に機能します(ただし、特に大きな範囲の場合、メモリの使用量がはるかに少なくなります)。


1
これについても説明してもらえますか、また、PythonのWebサイト/ PDFブックを推薦してもらえますか
ramesh.mimit

8
@ramesh help(range)Pythonシェルで実行すると、引数が表示されます。これらは、開始する数、終了する数(排他的)、および実行するステップであるため、9から始まり、-1になるまで1を減算します(その時点で、戻りなしで停止します。これが理由です。範囲は0で終了します)
Michael Mrozek

3
@ ramesh.mimit:公式のPythonサイトにアクセスしてください。すばらしいチュートリアルを含む完全なドキュメントがあります。
John Y

5
これは正解ですが、もっと明確に説明できます。 range(start, stop, step) -数値から開始し、到達しstartない限り結果を生成しstopstep毎回移動します。
B氏

43

range(10)[::-1]と同じものでrange(9, -1, -1)あり、間違いなく読みやすいものを使用できます(一般的なsequence[::-1]Pythonイディオムに精通している場合)。


28

これまでに収集されたオプションの「効率」に興味がある人のために...

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による表記を使用すると覚えやすいです


3
私はこの答えを読む前に自分のタイミングを計り、同じ結果を得ました。
トッドオーウェン

13
for i in range(8, 0, -1)

この問題を解決します。8から1を出力し、-1は逆リストを意味します


10

reverserangeメソッドは逆リストを返す可能性があるため、使用しても意味がありません。

n個のアイテムを反復処理しrange(start, stop, step)ていて、返されたリストの順序を置き換えたい場合は、それを識別してに設定する範囲の3番目のパラメーターを使用する必要があります。他のパラメーターはそれに応じて調整されます。step-1

  1. 提供停止などのパラメータを-1(それが以前の値だstop - 1stopと等しかったです0)。
  2. 開始パラメータとしてを使用しますn-1

したがって、range(n)の逆順での等価は次のようになります。

n = 10
print range(n-1,-1,-1) 
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

6
率直に言って、これは直感的にわかりにくいreversed(range(n))
ニコラスハミルトン

1
@NicholasHamilton同意しますが、その答えの背後にある考えは、より少ないリソースを使用することです...(そして問題は、範囲関数だけを使用することについてでした:))
Andriy Ivaneyko

OK、心配ありません、状況次第ではないでしょうか。たとえば、範囲関数がループのインデックスとして使用されている場合、効果は限定的ですが、外部ループ内で使用されている場合、コストは増大します...
Nicholas Hamilton

8

読みやすさはさておき、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)
Wolf

... timeit range(1000000000-1,-1,-1)コマンドラインを試さないでください。代わりに私の結果を確認しください:-)
Wolf

6

この質問の要件で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]

2
私はトリプルが-1本当に好きです。このパターンこそが維持を容易にしますwrap one's head around this-今日、本当に効率的でなければならないならrange(n-1, -1, -1)、逆の順序で範囲をトラバースするときに使用することを学びました。
Wolf

5

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のように動作します


5

非常によくある質問は、Python 3 range(9, -1, -1)よりも優れているかどうかreversed(range(10))です。イテレータを使用して他の言語で作業したことがある人は、reversed()がすべての値をキャッシュしてから逆の順序で戻る必要があるとすぐに思う傾向があります。ことはreversed()、オブジェクトが単なるイテレータである場合、Pythonの演算子は機能しないということです。reverse()が機能するためには、オブジェクトが2つ以下のいずれかでなければなりません。

  1. サポートlen()と整数インデックスのいずれか[]
  2. または、__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))パフォーマンスに影響を与えることなく使用できます。



3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

13
あなたの答えは、なぜreversed(range(10))エラーが起こりにくいのかを示しています。アシノックスを攻撃しません。正直なところ。
のMichałŠrajer

誤った答えを表示するのが標準であるかどうかはわかりません。私または誰かが修正したり、削除したりできますか?
sinekonata 2014年

3
@sine、いや、それはそのままにして、3つの賛成票がどのように蓄積されたのか疑問に思います...モデレーターの注意(壊れていることを除いて、18か月前からの回答の重複)にフラグを立てることができると思いますが、削除されたかどうかはわかりません。
OGHaza

今後の参考資料として、コードのみはVLQではなく間違った回答にもフラグが立てられることはありません。反対票を投じて続行しますが、この場合、NAAであれmod-flagingであれ、フラグ付けは間違っています。- レビューから
ゾーイ

2

[::-1]なしで使用または逆転-

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")

6
なぜこれの代わりに誰かがこれを書くべき"python!"[::-1]ですか?
ダニエル


1

必ずしもrange関数を使用する必要はありません。list[::-1]を実行するだけで、追加を使用せずにリストを逆順ですばやく返すことができます。


これは、以前の回答で提案された解決策のようです。また、以前の別の回答についてコメントしようとしている可能性もあります。そのためには、もう少し評判を得る必要があります。
Grisha Levit 2017年

1

リストがa = {1,2,3,4,5}というリストがあるとします。リストを逆に印刷したい場合は、次のコードを使用します。

a.reverse
for i in a:
   print(i)

範囲の使用を尋ねたのはわかっていますが、すでに回答されています。


0
range(9,-1,-1)
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

正しい形です。使用する場合

reversed(range(10))

あなたは0ケースを取得しません。たとえば、10はマジックナンバーではなく、逆方向から検索を開始するために使用している変数だとします。nのケースが0の場合、reversed(range(0))は実行されません。これは、偶然にゼロのインデックスに単一のオブジェクトがある場合は間違っています。


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)

MichałŠrajerの答え

%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でテスト済み

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.