Pythonは優れており、慎重に検討して使用方法を学ぶ価値のある高度な使用法が数多くあります。この記事では、リスト内包表記、イテレーターとジェネレーター、デコレーターなど、日常の使用に基づいたPythonの一連の高度な機能を要約して紹介します。
シナリオ1:1次元データが3次元リストにあるすべての要素を組み合わせて、新しい2次元リストを作成します。
最も簡単な方法:新しいリストを作成し、元の3次元リストをトラバースして、1次元データがaであるかどうかを判別し、そうである場合は、要素を新しいリストに追加します。
短所:コードが煩雑すぎるため、Pythonの場合、実行速度が大幅に遅くなります。
シナリオ1の場合、最初にリスト内包表記を使用して処理を解決することを検討する必要があります。1行のコードを解決できます。
lista =[item for item in array if item[0]=='a']
それで、リストの理解とは何ですか?
公式説明:リスト内包表記は組み込みのPythonであり、非常にシンプルですが、リストの作成に使用できる強力なジェネレーティブです。
**強くなるには? ****
ご覧のとおり、リスト内包表記の使用は短くなります。また、Pythonの組み込みの使用法であるため、最下層はC言語で実装され、Pythonコードを作成するよりも高速です。
シナリオ2:リストの場合、インデックスと要素の両方をトラバースする必要があります。
ここでは、Pythonの組み込み関数enumerateを使用して、ループ内のインデックスをより適切に取得できます。
array =['I','love','Python']for i, element inenumerate(array):
array[i]='%d: %s'%(i, seq[i])
リスト内包表記を使用してリファクタリングできます。
def getitem(index, element):return'%d: %s'%(index, element)
array =['I','love','Python']
arrayIndex =[getitem(index, element)for index, element inenumerate(array)]
この書き方はもっとPython的だと言われています。
概要:既存の反復可能オブジェクトに対して何らかの処理を実行してから新しいリストを生成する場合は、リスト内包表記を使用するのが最も便利な方法です。
ここでの反復は、forループを参照できます。Pythonでは、リスト、dict、ファイルなどのforループを使用できますが、これらは反復子ではなく、反復可能なオブジェクトに属します。
どのような反復可能なオブジェクト
最も簡単な説明:for ... in ...ステートメントを使用してループできるオブジェクトは反復可能なオブジェクト(Iterable)であり、isinstance()メソッドで判断できます。
from collections import Iterable
type =isinstance('python', Iterable)
print type
イテレーターとは
イテレーターとは、next()メソッドを使用してコールバックできるオブジェクトを指します。イテラブルオブジェクトでiter()メソッドを使用して、イテレーターに変換できます。
temp =iter([1,2,3])
print type(temp)
print next(temp)
この時点で、tempはイテレーターです。したがって、反復子は2つの方法に基づいています。
next()関数で呼び出して、次の値を継続的に返すことができるオブジェクトはイテレーターであることが理解できます。デコレーターを定義するときは、両方のメソッドを定義する必要があります。
イテレーターの利点
イテレーターを作成する場合、すべての要素を一度にロードする代わりに、次のメソッドが呼び出されたときに要素が返されるため、メモリの問題を考慮する必要はありません。
イテレーターアプリケーションのシナリオ
では、どのようなシナリオでイテレーターを使用できますか?
ジェネレーターは、一連の要素を返す必要のある関数に必要なコードをより単純かつ効率的にする高レベルの反復子です(反復子コードの作成ほど冗長ではありません)。
ジェネレーター機能
ジェネレーター関数はyield命令に基づいており、関数を一時停止して中間結果を返すことができます。シーケンスを返す、またはループで実行する関数が必要な場合は、ジェネレーターを使用できます。これらの要素が後続の処理のために別の関数に渡される場合、一度に1つの要素を返すと、全体的なパフォーマンスが効果的に向上するためです。
一般的なアプリケーションシナリオは、ジェネレータのストリームデータバッファを使用することです。
ジェネレータ式
生成式は、リスト内包表記の括弧を括弧に置き換えることにより、ジェネレーターを実装するための便利な方法です。
リスト内包表記との違い:リスト内包表記は直接テーブルを作成できますが、ジェネレータ式はループ中の計算であるため、完全なリストを作成しなくても、ループ中にリストの要素を1つずつ計算できます。 、それによって多くのスペースを節約します。
g =(x * x for x inrange(10))
概要:ジェネレーターは高レベルのイテレーターです。ジェネレータの利点は、計算を遅らせ、一度に1つの結果を返すことです。これは、大量のデータを使用する計算に非常に適しています。ただし、ジェネレーターを使用するときに注意しなければならないことの1つは、ジェネレーターは1回しかトラバースできないということです。
ラムダ式は、純粋に単純な関数を作成することを目的として設計されており、簡略化された関数を実行して、単純な関数をより簡潔にします。
ラムダとデフの違い
ラムダ式は、関数を定義するプロセスを節約し、コードをより簡潔にし、単純な関数に適しており、大企業を扱う関数を記述して、def定義を使用する必要があります。
ラムダ式は、map()、reduce()、filter()関数でよく使用されます
# リスト内の数値を文字列に変換する
map(str,[1,2,3,4,5,6])
reduce():関数は2つのパラメーターを受け取ります。1つは関数で、もう1つはシーケンスです。ただし、累積計算のために結果とシーケンスの次の要素を続行するには、関数は2つのパラメーターreduceを受け取る必要があります。効果はreduce(f、[x1 、x2、x3、x4])= f(f(f(x1、x2)、x3)、x4)。
filter():この関数は、フィルタリングし、渡された関数を各要素に順番に適用し、関数の戻り値がTrueかFalseかに従って、要素を保持するか破棄するかを決定するために使用されます。
デコレータは本質的にPython関数であり、他の関数がコードを変更せずに関数を追加できるようにします。デコレータを使用すると、関数自体とは関係のない多くの同様のコードを抽出して、それを再利用し続けることができます。これは、ログの挿入、パフォーマンステスト、トランザクション処理、キャッシュ、権限の検証など、アスペクト要件のあるシナリオでよく使用されます。
では、なぜデコレータを導入するのでしょうか。
シナリオ:関数の実行時間を計算します。
1つの方法は、関数の実行時間を具体的に計算する関数を定義し、実行時間の計算が完了した後に実際のビジネスコードを処理することです。コードは次のとおりです。
import time
def get_time(func):
startTime = time.time()func()
endTime = time.time()
processTime =(endTime - startTime)*1000
print "The function timing is %f ms"%processTime
def myfunc():
print "start func"
time.sleep(0.8)
print "end func"get_time(myfunc)myfunc()
ただし、このコードのロジックは元のコードロジックを破壊します。つまり、すべてのfunc関数の呼び出しは、get_time(func)を使用して実装する必要があります。
それで、それを表示するためのより良い方法はありますか?もちろんあります、それは装飾者です。
簡単なデコレータを書く
上記の例を組み合わせて、デコレータを作成します。
def get_time(func):
def wrapper():
startTime = time.time()func()
endTime = time.time()
processTime =(endTime - startTime)*1000
print "The function timing is %f ms"%processTime
return wrapper
print "myfunc is:", myfunc.__name__
myfunc =get_time(myfunc)
print "myfunc is: ", myfunc.__name__
myfunc()
このようにして、シンプルで完全なデコレータが実装されます。デコレータは、実行ロジックや関数の呼び出しに影響を与えないことがわかります。
Pythonでは、「@」構文シュガーを使用してデコレータコードを合理化できます。上記の例を次のように変更します。
@ get_time
def myfunc():
print "start func"
time.sleep(0.8)
print "end func"
print "myfunc is: ", myfunc.__name__
myfunc()
** デコレータの呼び出し順序**
デコレータはスタックで使用できます。複数のデコレータが同時に関数をデコレートする場合、デコレータの呼び出し順序は@ Syntax Sugarの宣言順序と逆になります。つまり、次のようになります。
@ decorator1
@ decorator2
def func():
pass
に等しい:
func = decorator1(decorator2(func()))
装飾された関数はパラメータを取ります
上記の例では、myfunc()にはパラメーターがありません。パラメーターを追加する場合、デコレーターの記述方法は?
# パラメータ付きの装飾機能
def get_time3(func):
def wrapper(*args,**kwargs):
startTime = time.time()func(*args,**kwargs)
endTime = time.time()
processTime =(endTime - startTime)*1000
print "The function timing is %f ms"%processTime
return wrapper
@ get_time3
def myfunc2(a):
print "start func"
print a
time.sleep(0.8)
print "end func"
a ="test"myfunc2(a)
パラメータ付きデコレータ
デコレータは柔軟性が高く、パラメータをサポートしています。たとえば、上記の例では、@ get_timeデコレータのパラメータは、ビジネスを実行する関数のみです。もちろん、論理的な判断のためにデコレータにパラメータを追加することもできます。
Pythonでは、一般的なクラスデコレータには、@ staticmathod、@ classmethod、および@propertyが含まれます。
上記は今回コンパイルしたPythonの高度な使い方であり、この記事は今後も更新されていきます。
Recommended Posts