5.5。 データ構造
この章では、すでに学んだいくつかのことをより詳細に説明し、いくつかの新しいことも追加します。
5.1。 リストの詳細
リストデータ型には、さらにいくつかのメソッドがあります。 リストオブジェクトのすべてのメソッドは次のとおりです。
- list.append(x)
- リストの最後にアイテムを追加します。
a[len(a):] = [x]
と同等です。
- list.extend(L)
- 指定されたリストのすべての項目を追加して、リストを拡張します。
a[len(a):] = L
と同等です。
- list.insert(i, x)
- 指定された位置にアイテムを挿入します。 最初の引数は挿入する前の要素のインデックスであるため、
a.insert(0, x)
はリストの先頭に挿入され、a.insert(len(a), x)
はa.append(x)
と同等です。
- list.remove(x)
- 値が x の最初のアイテムをリストから削除します。 そのようなアイテムがない場合はエラーです。
- list.pop([i])
- リスト内の指定された位置にあるアイテムを削除して、返却します。 インデックスが指定されていない場合、
a.pop()
はリストの最後のアイテムを削除して返します。 (メソッドシグニチャの i を囲む角かっこは、パラメータがオプションであることを示しており、その位置に角かっこを入力する必要はありません。 この表記は、Pythonライブラリリファレンスで頻繁に見られます。)
- list.index(x)
- 値が x である最初のアイテムのリストのインデックスを返します。 そのようなアイテムがない場合はエラーです。
- list.count(x)
- x がリストに表示された回数を返します。
- list.sort(cmp=None, key=None, reverse=False)
- リストの項目をその場でソートします(引数はソートのカスタマイズに使用できます。説明については、 sorted()を参照してください)。
- list.reverse()
- リストの要素を元の場所に戻します。
ほとんどのリストメソッドを使用する例:
リストを変更するだけのinsert
、remove
、sort
のようなメソッドには、戻り値が出力されないことに気付いたかもしれません。デフォルトのNone
を返します。 これは、Pythonのすべての可変データ構造の設計原則です。
5.1.1。 リストをスタックとして使用する
listメソッドを使用すると、リストをスタックとして非常に簡単に使用できます。ここで、最後に追加された要素は、最初に取得された要素(「後入れ先出し」)です。 スタックの一番上にアイテムを追加するには、append()
を使用します。 スタックの最上位からアイテムを取得するには、明示的なインデックスなしでpop()
を使用します。 例えば:
5.1.2。 リストをキューとして使用する
リストをキューとして使用することもできます。ここで、追加された最初の要素は、取得された最初の要素です(「先入れ先出し」)。 ただし、リストはこの目的には効率的ではありません。 リストの最後からの追加とポップは高速ですが、リストの最初からの挿入またはポップの実行は低速です(他のすべての要素を1つシフトする必要があるため)。
キューを実装するには、両端からの高速な追加とポップを行うように設計された collections.deque を使用します。 例えば:
5.1.3。 関数型プログラミングツール
リストで使用すると非常に便利な3つの組み込み関数があります: filter()、 map()、および reduce()。
filter(function, sequence)
は、function(item)
が真であるシーケンスからのアイテムで構成されるシーケンスを返します。 sequence が str 、 unicode 、または tuple の場合、結果は同じタイプになります。 それ以外の場合は、常にlist
です。 たとえば、3または5で割り切れる数のシーケンスを計算するには:
map(function, sequence)
は、シーケンスの各項目に対してfunction(item)
を呼び出し、戻り値のリストを返します。 たとえば、いくつかのキューブを計算するには、次のようにします。
複数のシーケンスを渡すことができます。 この場合、関数にはシーケンスと同じ数の引数が必要であり、各シーケンスの対応するアイテムで呼び出されます(または、あるシーケンスが別のシーケンスより短い場合はNone
)。 例えば:
reduce(function, sequence)
は、シーケンスの最初の2つの項目、次に結果と次の項目というように、バイナリ関数 function を呼び出して作成された単一の値を返します。 たとえば、1から10までの数値の合計を計算するには、次のようにします。
シーケンスにアイテムが1つしかない場合は、その値が返されます。 シーケンスが空の場合、例外が発生します。
3番目の引数を渡して、開始値を示すことができます。 この場合、空のシーケンスに対して開始値が返され、関数は最初に開始値と最初のシーケンス項目に適用され、次に結果と次の項目に適用されます。 例えば、
この例の sum()の定義は使用しないでください。数値の合計は非常に一般的なニーズであるため、組み込み関数sum(sequence)
がすでに提供されており、まったく同じように機能します。
5.1.4。 リスト内包表記
リスト内包表記は、リストを作成するための簡潔な方法を提供します。 一般的なアプリケーションは、各要素が別のシーケンスまたは反復可能の各メンバーに適用された操作の結果である新しいリストを作成するか、特定の条件を満たす要素のサブシーケンスを作成することです。
たとえば、次のような正方形のリストを作成するとします。
次の方法でも同じ結果を得ることができます。
これもsquares = map(lambda x: x**2, range(10))
と同等ですが、より簡潔で読みやすくなっています。
リスト内包表記は、式とそれに続く for 句、および0個以上の for または if 句を含む角かっこで構成されます。 結果は、それに続く for および if 句のコンテキストで式を評価した結果の新しいリストになります。 たとえば、このlistcompは、2つのリストの要素が等しくない場合、それらを組み合わせます。
そしてそれは同等です:
for ステートメントと if ステートメントの順序がこれらのスニペットの両方でどのように同じであるかに注意してください。
式がタプルの場合(例: 前の例の(x, y)
)、括弧で囲む必要があります。
リスト内包表記には、複雑な式やネストされた関数を含めることができます。
5.1.4.1。 ネストされたリスト内包
リスト内包表記の最初の式は、別のリスト内包表記を含む任意の式にすることができます。
長さ4の3つのリストのリストとして実装された3x4行列の次の例を考えてみます。
次のリスト内包表記は、行と列を転置します。
前のセクションで見たように、ネストされたlistcompは、それに続く for のコンテキストで評価されるため、この例は次のようになります。
これは、次と同じです。
現実の世界では、複雑なフローステートメントよりも組み込み関数を優先する必要があります。 zip()関数は、このユースケースに最適です。
この行のアスタリスクの詳細については、引数リストの解凍を参照してください。
5.2。 NS デル声明
値の代わりにインデックスを指定してリストからアイテムを削除する方法があります: del ステートメント。 これは、値を返すpop()
メソッドとは異なります。 del ステートメントを使用して、リストからスライスを削除したり、リスト全体をクリアしたりすることもできます(これは、以前にスライスに空のリストを割り当てることで行いました)。 例えば:
del を使用して、変数全体を削除することもできます。
以降、a
という名前を参照すると、エラーになります(少なくとも別の値が割り当てられるまで)。 del の他の用途については後で説明します。
5.3。 タプルとシーケンス
リストと文字列には、インデックス作成やスライス操作など、多くの一般的なプロパティがあることがわかりました。 これらはシーケンスデータ型の2つの例です(シーケンスタイプ— str、unicode、list、tuple、bytearray、buffer、xrange を参照)。 Pythonは進化する言語であるため、他のシーケンスデータ型が追加される場合があります。 別の標準シーケンスデータ型もあります:タプル。
タプルは、コンマで区切られたいくつかの値で構成されます。次に例を示します。
ご覧のとおり、出力時のタプルは常に括弧で囲まれているため、ネストされたタプルは正しく解釈されます。 とにかく括弧が必要になることがよくありますが、それらは周囲の括弧の有無にかかわらず入力できます(タプルがより大きな式の一部である場合)。 タプルの個々のアイテムに割り当てることはできませんが、リストなどの可変オブジェクトを含むタプルを作成することはできます。
タプルはリストに似ているように見えるかもしれませんが、さまざまな状況でさまざまな目的で使用されることがよくあります。 タプルは不変であり、通常、アンパック(このセクションの後半を参照)またはインデックス付け( namedtuples の場合は属性によっても)を介してアクセスされる要素の異種シーケンスが含まれます。 リストは可変であり、それらの要素は通常同種であり、リストを反復処理することでアクセスされます。
特別な問題は、0個または1個の項目を含むタプルの構築です。構文には、これらに対応するためのいくつかの追加の癖があります。 空のタプルは、空の括弧のペアで構成されます。 1つの項目を持つタプルは、値の後にコンマを付けて作成されます(1つの値を括弧で囲むだけでは不十分です)。 醜いですが、効果的です。 例えば:
ステートメントt = 12345, 54321, 'hello!'
は、タプルパッキングの例です。値12345
、54321
、および'hello!'
はタプルに一緒にパックされます。 逆の操作も可能です。
これは、適切にはシーケンスアンパックと呼ばれ、右側の任意のシーケンスで機能します。 シーケンスのアンパックでは、左側の変数のリストに、シーケンスの長さと同じ数の要素が必要です。 複数の割り当ては、実際にはタプルパッキングとシーケンスアンパックの単なる組み合わせであることに注意してください。
5.4。 セット
Pythonには、セットのデータ型も含まれています。 セットは、重複する要素のない順序付けられていないコレクションです。 基本的な用途には、メンバーシップのテストと重複エントリの排除が含まれます。 セットオブジェクトは、和集合、共通部分、差、対称差などの数学演算もサポートします。
中括弧または set()関数を使用してセットを作成できます。 注:空のセットを作成するには、{}
ではなくset()
を使用する必要があります。 後者は空の辞書を作成します。これは次のセクションで説明するデータ構造です。
簡単なデモンストレーションは次のとおりです。
リスト内包表記と同様に、集合の内包表記もサポートされています。
5.5。 辞書
Pythonに組み込まれているもう1つの便利なデータ型は、辞書です(マッピングタイプ— dict を参照)。 辞書は、他の言語では「連想記憶」または「連想配列」として見つかることがあります。 ある範囲の数値で索引付けされるシーケンスとは異なり、辞書はキーで索引付けされます。これは、任意の不変タイプにすることができます。 文字列と数字は常にキーにすることができます。 タプルに文字列、数字、またはタプルのみが含まれている場合は、タプルをキーとして使用できます。 タプルに直接または間接的に変更可能なオブジェクトが含まれている場合、それをキーとして使用することはできません。 リストは、インデックス割り当て、スライス割り当て、またはappend()
やextend()
などのメソッドを使用してその場で変更できるため、リストをキーとして使用することはできません。
ディクショナリは、 key:value ペアの順序付けられていないセットと考えるのが最善です。ただし、キーは(1つのディクショナリ内で)一意である必要があります。 中括弧のペアは空の辞書を作成します:{}
。 中括弧内にkey:valueペアのコンマ区切りリストを配置すると、最初のkey:valueペアがディクショナリに追加されます。 これは、辞書が出力に書き込まれる方法でもあります。
ディクショナリの主な操作は、キーを使用して値を格納し、キーを指定して値を抽出することです。 del
でキーと値のペアを削除することもできます。 すでに使用されているキーを使用して保存すると、そのキーに関連付けられている古い値は忘れられます。 存在しないキーを使用して値を抽出するとエラーになります。
ディクショナリオブジェクトのkeys()
メソッドは、ディクショナリで使用されているすべてのキーのリストを任意の順序で返します(ソートする場合は、 sorted()関数を適用するだけです)。 。 単一のキーが辞書にあるかどうかを確認するには、 in キーワードを使用します。
辞書を使用した小さな例を次に示します。
dict()コンストラクターは、キーと値のペアのシーケンスから直接辞書を作成します。
さらに、dict内包表記を使用して、任意のキーおよび値式から辞書を作成できます。
キーが単純な文字列の場合、キーワード引数を使用してペアを指定する方が簡単な場合があります。
5.6。 ループテクニック
シーケンスをループする場合、 enumerate()関数を使用して、位置インデックスと対応する値を同時に取得できます。
2つ以上のシーケンスを同時にループするには、エントリを zip()関数とペアにすることができます。
シーケンスを逆方向にループするには、最初に順方向のシーケンスを指定してから、 reverse()関数を呼び出します。
ソートされた順序でシーケンスをループするには、 sorted()関数を使用します。この関数は、ソースを変更せずに、新しいソートされたリストを返します。
辞書をループする場合、iteritems()
メソッドを使用して、キーと対応する値を同時に取得できます。
リストをループしているときに、リストを変更したくなることがあります。 ただし、多くの場合、代わりに新しいリストを作成する方が簡単で安全です。
5.7。 条件の詳細
while
およびif
ステートメントで使用される条件には、比較だけでなく、任意の演算子を含めることができます。
比較演算子in
およびnot in
は、値がシーケンスで発生する(発生しない)かどうかをチェックします。 演算子is
とis not
は、2つのオブジェクトが本当に同じオブジェクトであるかどうかを比較します。 これは、リストなどの可変オブジェクトにのみ関係します。 すべての比較演算子の優先度は同じであり、すべての数値演算子の優先度よりも低くなっています。
比較は連鎖させることができます。 たとえば、a < b == c
は、a
がb
未満であり、さらにb
がc
と等しいかどうかをテストします。
ブール演算子and
およびor
を使用して比較を組み合わせることができ、比較(または他のブール式)の結果はnot
で否定できます。 これらは、比較演算子よりも優先度が低くなります。 それらの間では、not
の優先度が最も高く、or
の優先度が最も低いため、A and not B or C
は(A and (not B)) or C
と同等です。 いつものように、括弧を使用して目的の構成を表すことができます。
ブール演算子and
およびor
は、いわゆる短絡演算子です。これらの引数は左から右に評価され、結果が決定されるとすぐに評価が停止します。 。 たとえば、A
とC
が真であるが、B
が偽である場合、A and B and C
は式C
を評価しません。 ブール値としてではなく一般値として使用される場合、短絡演算子の戻り値は最後に評価される引数です。
比較または他のブール式の結果を変数に割り当てることができます。 例えば、
Pythonでは、Cとは異なり、式の内部で代入を行うことはできないことに注意してください。 Cプログラマーはこれについて不平を言うかもしれませんが、Cプログラムで発生する一般的なクラスの問題を回避します。==
が意図されたときに式に=
と入力します。
5.8。 シーケンスと他のタイプの比較
シーケンスオブジェクトは、同じシーケンスタイプの他のオブジェクトと比較できます。 比較では、辞書式の順序を使用します。最初に最初の2つの項目が比較され、それらが異なる場合は、これによって比較の結果が決まります。 それらが等しい場合は、次の2つの項目が比較され、いずれかのシーケンスが使い果たされるまで続きます。 比較する2つの項目自体が同じタイプのシーケンスである場合、辞書式比較は再帰的に実行されます。 2つのシーケンスのすべての項目が等しいと比較される場合、シーケンスは等しいと見なされます。 一方のシーケンスがもう一方の最初のサブシーケンスである場合、短いシーケンスは小さい(小さい)シーケンスです。 文字列の辞書式順序は、個々の文字のASCII順序を使用します。 同じタイプのシーケンス間の比較のいくつかの例:
異なるタイプのオブジェクトを比較することは合法であることに注意してください。 結果は決定論的ですが任意です。タイプは名前順に並べられています。 したがって、リストは常に文字列よりも小さく、文字列は常にタプルよりも小さいなどです。 1 混合数値型は数値に従って比較されるため、0は0.0になります。
脚注
- 1
- 異なるタイプのオブジェクトを比較するためのルールは信頼されるべきではありません。 それらは、言語の将来のバージョンで変更される可能性があります。