辞書ジェネレーター

Python言語の優れた機能のいくつかは、当然のことながら無視され、多くのプログラマーはそれらについて知らない。 今回は、コードをより明確にする言語の優れた機能について説明します。辞書ジェネレーターは、辞書を返す単一行の式です。 しかし、コンパクトなリストジェネレーターと、コレクションの一意でない要素を削除するタスクから始めましょう。



主にPythonの初心者にとって興味深いものになります。



リストジェネレーター




リストを作成する最も簡単な方法は、1行の式-リストジェネレーターを使用することです。 これは非常に頻繁に使用され、多くの例と多くのライブラリのコードで会いました。

リストを返す関数があるとします。 良い例は、 範囲(開始、終了)関数です。これは、 開始終了の間の数値を返します。 バージョンPython 3.0以降では、 ジェネレーターとして実装されており、すぐには完全なリストを返しませんが、必要に応じて番号ごとに番号を付けます。 Python 2 *では、 xrange()関数がこれに使用されました。 この関数を使用して1から10までの数字のリストを取得すると、次のようになります。

numbers = [] for i in range(1, 11): numbers.append(i)
      
      





偶数のみが必要な場合は、次のように実装できます。

 numbers = [] for i in range(1, 11): if i % 2 == 0: numbers.append(i)
      
      





リストジェネレーターを使用すると、コードが非常に簡単になります。 これは、式が一般形式でリストを返す方法です。

 [ expression for item in list if conditional ]
      
      





これを使用して、最初の例を次のように書き換えることができます。

 numbers = [i for i in range(1, 11)]
      
      





2番目は次のようなものです。

 numbers = [i for i in range(1, 11) if i % 2 == 0]
      
      





もちろん、このような構文は一見奇妙に見えるかもしれませんが、慣れるとコードがよりシンプルで理解しやすくなります。



重複削除


コレクションを操作するときのもう1つの一般的なタスクは、同じ要素を削除することです。 多くの方法で解決できます。

次のようなリストで作業しているとします:

 numbers = [i for i in range(1,11)] + [i for i in range(1,6)]
      
      





私が遭遇した重複を削除する最も難しい方法は次のようになります:

 unique_numbers = [] for n in numbers: if n not in unique_numbers: unique_numbers.append(n)
      
      





もちろんこれは機能しますが、もっと簡単な解決策があります。 標準タイプセットを使用できます。 多くの場合、同じ要素を定義上含めることができないため、リストを多数に変換すると、重複が削除されます。 ただし、リストではなくセットを取得するため、一意の値のリストが必要な場合は、再度変換する必要があります。

 unique_numbers = list(set(numbers))
      
      







重複するオブジェクトを削除する


オブジェクトまたは辞書のまったく異なる状況。 たとえば、値の1つが識別子として使用される辞書のリストがあります。

 data = [ {'id': 10, 'data': '...'}, {'id': 11, 'data': '...'}, {'id': 12, 'data': '...'}, {'id': 10, 'data': '...'}, {'id': 11, 'data': '...'}, ]
      
      





繰り返しの削除は、多少のコード​​で実装できます。 もちろん、少ないほど良い! 長いバージョンは次のようになります。

 unique_data = [] for d in data: data_exists = False for ud in unique_data: if ud['id'] == d['id']: data_exists = True break if not data_exists: unique_data.append(d)
      
      







私が数日前に学んだ機会を使って同じ結果を得ることができます:辞書ジェネレーター。 それらはリストジェネレータに似た構文を持っていますが、辞書を返します:

 { key:value for item in list if conditional }
      
      





この機能を使用して上記の例のコードを書き換えると、1行のみが残ります。

 { d['id']:d for d in data }.values()
      
      





このコード行でディクショナリが作成されます。キーは一意の識別子として取得したフィールドであり、values()メソッドを使用して、作成したディクショナリからすべての値を取得します。 なぜなら ディクショナリにはキーごとに1つのエントリしか含めることができません。結果のリストには、必要な重複が含まれていません。

この機能はPython 3.0で追加され、Python 2.7でバックポートされました。以前のバージョンでは、同様の問題を解決するために、次のタイプの構成を使用できます。

 dict((key, value) for item in list if condition)
      
      





タプル(ペア)のリストが生成され、コンストラクターdict()に渡されます。これは、タプルの最初の要素をキーとして、2番目の要素を値として受け取ります。 このアプローチでは、同じ問題の解決策は次のようになります。

 dict((d['id'], d) for d in data).values()
      
      






All Articles