Python 3範囲をリストに変換


178

数字の1-1000入ったリストを作ろうとしています。明らかに、これは書き込み/読み取りが面倒なので、範囲を指定してリストを作成しようとしています。Python 2ではそれはようです:

some_list = range(1,1000)

うまくいきましたが、Python 3の範囲はxrangePython 2の範囲と似ていますか?

誰かがこれについて何らかの洞察を提供できますか?


1
また、some_list[i] == i+1なので、とにかくリストは本当に必要ないでしょう。
njzk2 14

1
@RikPoggi。たとえば、プロット関数のリストを提供する必要があるかもしれません。範囲で十分な場合もありますが、範囲を連結することはできません(不変です)。したがって、プロットされるすべてのリストにデフォルトの開始値を追加する必要がある場合は、その値もリストに変換する必要があります。
SherylHohman 2017

回答:


223

rangeオブジェクトからリストを作成するだけです:

my_list = list(range(1, 1001))

これは、python2.xのジェネレーターでも同様です。my_list[i]より効率的に(i + 1)の値を取得できるため、通常はリストは必要ありませんが、反復するだけの場合は、に頼ることができますrange

また、python2.xでは、xrangeまだ索引付け可能1です。これは、rangepython3.xでも同じプロパティ2があることを意味します

1print xrange(30)[12]はpython2.xで動作します

2 python3.xの1と同様のステートメントがprint(range(30)[12])あり、これも機能します。


4
これは間違いなく進むべき道ですが、ちょっとしたことです:これは実際には「キャスト」ではありません
jterrace

@jterraceが「キャスト」を「変換」に変更しました。キャストではないというのはあなたの言うとおりです...私はそれを正確に何と呼ぶべきか本当に知りません。
mgilson 2012

2
私は「コンストラクト」または「ビルド」(または「マテリアライズ」)と言います-ジェネレータを(そのように)リストに「変換」していないので、発生するデータソースから新しいリストオブジェクトを作成していますジェネレーターになる...(しかし、髪を分割するだけで、とにかく私が何を好むか100%確信できない)
Jon Clements

2
他のオブジェクト指向言語と一貫しているため、私の「構成」の+1。list(arg)コンストラクタ呼び出しと他の言語で理解されているlistクラスを。実際、これはPythonのケースでもあります。(C ++の場合のように)構築中にオブジェクトが入力されるのか、それとも(Python __init__()メソッドのように)最初に自動的に呼び出されるメソッドの間にのみオブジェクトが入力されるのかについての議論は、基本的な抽象概念を変更できません。私の見解では、リスト・コンストラクターはイテレーターを取り、リストに戻り値を入れます
2012

2
jupyterノートブックでエラーが発生し、シェルで正常に動作するのはなぜですか?エラー:'range' object is not callable
subtleseeker

34

Pythonが3.4以下の場合、他の人が示唆list(range(10))しているように、範囲外のリストを作成するために使用できます(一般に、任意の反復可能)。

Python 3.5でアンパッキングの一般化とともに導入された別の方法*は、リストリテラルで使用すること[]です。

>>> r = range(10)
>>> l = [*r]
>>> print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

これはと同等ですがlist(r)、リテラル構文であり、関数呼び出しが含まれていないため、実行速度が速くなります。ゴルフをコーディングする必要がある場合は、文字数も少なくなります:-)


4
明確にするために、それを1行にすることもでき[*range(10)]ます。をrange初期化する以外の目的でが必要ない場合に問題なく機能しますlist。補足:展開の一般化の私のお気に入り(大丈夫ですが、実際にはそうではありません)は、空setのにはリテラル構文{*()}、または私が言うところの片目モンキーオペレーターがあるということです。;-)
ShadowRanger 2017年

@ShadowRangerは、私が最初にそれを書くことを考えた方法です。新しいPythonユーザーを混乱させないために、もう少し冗長にすることにしました:-)
Dimitris Fasarakis Hilliard

26

Python 3.xでは、range()関数は独自の型を持ちました。この場合、イテレータを使用する必要があります

list(range(1000))


11
「この場合、イテレータを使用する必要があります」?一体何を意味しているのでしょうか?
user2357112はMonica

2
私はpython 3.7を使用していて、x = list(range(1000))を試しましたが、エラーTypeError: 'list' object is not callable
Earthshaker

@Earthshaker次のようなタイプミスが必要ですlist(range(1000))()
wjandrea

17

Python3に範囲リストを直接取得する機能がないのは、元のPython3デザイナーがPython2の初心者だったからです。彼range()はforループでの関数の使用のみを検討したため、リストを展開する必要はありません。実際、range()リストを作成して関数に渡すために、関数を使用する必要があることがよくあります。

したがって、この場合、Python3はPython2に比べて便利ではありません。

  • Python2では、xrange()range();
  • Python3ではrange()list(range())

それでも、この方法でリストの拡張を使用できます。

[*range(N)]

3
全体のポイントは、それはあまり便利にするようにすることですlistそれが行うには間違ったことは、通常だから、。100のユースケースのうち99の場合、実際の作成はほとんどすべての点で不変シーケンスのように動作し、場合によってはより効率的に起動するため(たとえば、の包含テストはとの比較です)list、非効率で無意味です。Python 2では、ほとんどの場合より優れたオプションでしたが、人々はデフォルトで使用する傾向がありました。Python 3では、誤った名前を使用して誤って取得するのではなく、明示的ににオプトインできます。rangeintO(1)O(n)listrangexrangelist
ShadowRanger

7
Python 3デザイナーと彼のPython 2に関する専門知識についてのコメントは、非常に大胆で無関心です。
カザリー

@kazareyしかし、それは本当ですか?これらの行に沿って疑わしい多くのものがpythonにあります
javadba

1
特にunpacking-shorthandでリストを作成する場合は賛成票を投じますが、@ kazareyに同意します。デザイナーに関するコメントは根拠がなく(または、少なくとも、参照に裏打ちされていない)、不要です。
Nubarke

12

リストで1〜1000の数字を使用する必要はありません。しかし、なんらかの理由でこれらの数値が本当に必要な場合は、次のようにすることができます。

[i for i in range(1, 1001)]

一言で理解をリストします:

上記のリストの理解は次のように変換されます。

nums = []
for i in range(1, 1001):
    nums.append(i)

これは2.xからのものですが、単なるリスト内包構文です。私はこれがPython 3で動作することを知っていますが、アップグレードされた構文があるかどうかはわかりません

範囲は、最初のパラメーターを含めて開始します。しかし、最大、終了を含まない(;最初のパラメータはオフに残っている場合、それは「0」で始めます2つのパラメータを供給する場合)2番目のパラメータは、

range(start, end+1)
[start, start+1, .., end]

20
なぜ理解するのか?Just:list(range(1000))
Rik Poggi

ありがとう!なぜi for iなのかを説明していただけませんか?
ボートハウス2012

私はpython3を使用していません。だから私はそれがどのように機能するかについて完全に確信していません。理解力が機能することは知っていますが、キャスティングでは100%ではありませんでした。しかし、キャスティングがうまくいけば、あなたは正しいですし、あなたのやり方はよりパイソン風です。
inspectorG4dget

1
@ inspectorG4dget:「キャスティング」ではなくlist()、iterableでコンストラクタを呼び出しています。list()コンストラクタは、任意の反復可能なオブジェクトを与えられたときに、新しいリストを作成する方法を知っています。
グレッグヒューギル2012

4
@ inspectorG4dget:list(range(1000))python3でもpython2と同じようlist(xrange(1000))に機能します
Rik Poggi

4

実際には、1〜1000(両端を含む)が必要な場合は、range(...)関数をパラメーター1と1001 で使用しますrange(1, 1001)。これは、range(start, end)関数が開始から(終了1)まで含まれるためです。


0

Python 3で範囲を使用します。

以下は、2つの数値から数値の間に戻る関数の例です。

def get_between_numbers(a, b):
    """
    This function will return in between numbers from two numbers.
    :param a:
    :param b:
    :return:
    """
    x = []
    if b < a:
        x.extend(range(b, a))
        x.append(a)
    else:
        x.extend(range(a, b))
        x.append(b)

    return x

結果

print(get_between_numbers(5, 9))
print(get_between_numbers(9, 5))

[5, 6, 7, 8, 9]  
[5, 6, 7, 8, 9]

これは別の質問に答えているようです...?
wjandrea

-1

実際、これはPython2と比較してPython3の旧バージョンです。確かに、range()とxrange()を使用するPython2は、それぞれlist(range())とrange()を使用するPython3よりも便利です。その理由は、Python3の元の設計者はあまり経験がなく、メモリとCPUの両方で非効率な多数の要素を反復するために、多くの初心者による範囲関数の使用のみを考慮したためです。しかし、彼らは数のリストを作成するためにrange関数の使用を無視しました。今、彼らがすでに元に戻すのは遅すぎます。

私がPython3のデザイナーになるとしたら、

  1. irangeを使用してシーケンスイテレータを返す
  2. lrangeを使用してシーケンスリストを返す
  3. rangeを使用して、シーケンスイテレータ(要素の数が多い場合、たとえばrange(9999999)またはシーケンスリスト(要素の数が少ない場合、たとえばrange(10))を返す

それが最適なはずです。


これはどのように質問に答えますか?
wjandrea

うん、それはPython3開発者にPython3の変更と改善を要求することで質問に答えます。しかし、それらはそれほどエレガントではないので、それらが変わることはほとんどありません。
xuancong84
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.