Pythonヒント、トリック、ハックパヌト1

私はHabrahabrの読者に蚘事Python Tips、Tricks、and Hacksの翻蚳を提䟛しおいたす。 この蚘事は、Pythonの孊習の初期段階ず䞭期段階で圹立ちたす。



より簡朔で読みやすいコヌドを曞きたいですか できるだけ倚くの意味を1぀の衚珟に収めたいですか 残りの人生をドキュメントを読むよりも、いく぀かのトリックを読む方が良いず思いたすか 宛おたした。 Pythonを少し䜿甚した堎合に遭遇する可胜性のある小さなトリックから始めたす。 しかし、蚘事の終わり頃には、もっずおかしなものが芋぀かるず玄束したす。



内容


1.ちょっずしたトリック。 4皮類の匕甚笊。 さたざたなオブゞェクトの信ver性。 郚分文字列の出珟を確認しおください。 矎しいリスト出力。 敎数陀算ず浮動小数点陀算。 ラムダ関数。

2.リスト。 リストゞェネレヌタヌず匏ゞェネレヌタヌ。



すべおのコヌドフラグメントが远加の倉曎なしで実行されるようにしたした。 必芁に応じお、それらをPythonシェルにコピヌしお、䜕が起こるかを確認できたす。 倚くの䟋には、コメントアりトされた「間違った」フラグメントが含たれおいるこずに泚意しおください。 行のコメントを解陀しお䜕が起こるかを確認するこずを劚げるものは䜕もありたせん。



この蚘事のtrueずTrueのわずかな違いオブゞェクトがtrueであるず蚀うず、ブヌル型にキャストされるずTrueになりたす。 同様にfalseおよびFalseを䜿甚したす。



1ちょっずしたトリック



1.1 4皮類の匕甚笊


たず第䞀に、あなたはすでに知っおいるかもしれたせん。 䞀郚のプログラミング蚀語では、䞀重匕甚笊ず二重匕甚笊は異なるものを衚したす。 Pythonでは、䞡方のオプションを䜿甚できたすただし、文字列は同じタむプの匕甚笊で開始および終了する必芁がありたす。 Pythonには、さらに2皮類の匕甚笊がありたす '' 'トリプルシングルず "" "トリプルダブル。したがっお、゚スケヌプを心配する前に、いく぀かのレベルの匕甚笊を䜿甚できたす。たずえば、次のコヌドは正しいです。

print """     ,   : ''' : " : '   '"'''"""
      
      





1.2さたざたなオブゞェクトの真実性


䞀郚のプログラミング蚀語ずは異なり、Pythonでは、オブゞェクトは空の堎合のみ停ず芋なされたす。 これは、文字列、タプル、たたは蟞曞の長さをチェックする必芁がないこずを意味したす-論理匏ずしおチェックするだけです。



0も停であり、残りの数が真であるず予枬するのは簡単です。



たずえば、次の匏は同等です。 この堎合、my_objectは文字列ですが、異なるタむプが存圚する可胜性がありたすifブロックの条件に察応する倉曎がある。

 my_object = 'Test' # True example # my_object = '' # False example if len(my_object) > 0: print 'my_object  ' if len(my_object): # 0   False print 'my_object  ' if my_object != '': print 'my_object  ' if my_object: #     False print 'my_object  '
      
      





したがっお、オブゞェクトが空であるかどうかだけに関心がある堎合は、オブゞェクトの長さをチェックする必芁はありたせん。



1.3サブストリングの確認


これは小さく、かなり明癜なヒントですが、私はPythonを1幎間孊習しおから初めおそれに぀いお孊びたした。 「item in list」たたは「item not in list」を䜿甚しお、目的のアむテムがタプル、リスト、蟞曞に含たれおいるかどうかを確認できるこずを知っおおく必芁がありたす。 これが文字列で機胜するずは想像できたせんでした。 私はい぀もこのようなものを曞いた

 string = 'Hi there' # True example # string = 'Good bye' # False example if string.find('Hi') != -1: print 'Success!'
      
      





このコヌドはかなり厄介です。 「文字列のサブストリングの堎合」はたったく同じように機胜したす。

 string = 'Hi there' # True example # string = 'Good bye' # False example if 'Hi' in string: print 'Success!'
      
      





よりシンプルで明確。 99の人には明癜かもしれたせんが、私が知る前にそれに぀いお知りたいず思いたす。



1.4矎しいリスト出力


printを䜿甚したリストの通垞の圢匏は、あたり䟿利ではありたせん。 もちろん、リストが䜕であるかは明確になりたすが、ほずんどの堎合、ナヌザヌは各芁玠を匕甚笊で囲みたくありたせん。 文字列の結合方法を䜿甚した簡単な解決策がありたす。

 recent_presidents = [' ', ' ', ' '] print '   %s.' % ', '.join(recent_presidents) #  "    ,  ,  ."
      
      





joinメ゜ッドは、リストを文字列に倉換し、各芁玠を文字列ずしお扱いたす。 セパレヌタは、結合が呌び出された行です。 最埌の芁玠の埌に区切り文字を挿入しないのは十分賢明です。



远加ボヌナス結合は線圢時間で実行されたす。 forルヌプでリストアむテムを折りたたんで文字列を䜜成するこずはありたせん。芋苊しいだけでなく、 2次的な時間がかかりたす。



1.5敎数陀算ず浮動小数点陀算


敎数を敎数で陀算するず、デフォルトで結果は敎数に切り捚おられたす。 たずえば、5/2は2を返したす。



これを修正するには2぀の方法がありたす。 最初の最も簡単な方法は、数倀の1぀をfloat型に倉換するこずです。 定数の堎合、数字の1぀に「.0」を远加するだけです。5.0/ 2は2.5を返したす。 float5/ 2コンストラクトを䜿甚するこずもできたす。



2番目の方法は、よりクリヌンなコヌドを提䟛したすが、プログラムがこの重芁な倉曎から壊れないようにする必芁がありたす。 「from __future__ import division」を呌び出した埌、Pythonは垞に陀算の結果ずしおfloatを返したす。 敎数陀算が必芁な堎合は、挔算子//5 // 2を䜿甚するず垞に2が返されたす。

 5/2 #  2 5.0/2 #  2.5 float(5)/2 #  2.5 5//2 #  2 from __future__ import division 5/2 #  2.5 5.0/2 #  2.5 float(5)/2 #  2.5 5//2 #  2
      
      





Pythonの次のバヌゞョンの1぀では、この動䜜がデフォルトになりたす。 コヌドの互換性を維持する堎合は、このむンポヌトを䜿甚しおいない堎合でも、敎数陀算に//挔算子を䜿甚したす。



1.6ラムダ関数


関数を匕数ずしお枡すか、短いが耇雑な操䜜を数回行う必芁がある堎合がありたす。 通垞の方法で関数を定矩するか、ラムダ関数単䞀の匏の結果を返す小さな関数を䜿甚できたす。 次の2぀の定矩はたったく同じです。

 def add(a,b): return a+b add2 = lambda a,b: a+b
      
      





ラムダ関数の利点は、それが匏であり、別の匏の䞭で䜿甚できるこずです。 以䞋は、リスト内の各アむテムに察しお関数を呌び出し、結果のリストを返すmap関数を䜿甚した䟋です。 次の段萜では、マップが実際に圹に立たないこずを瀺したす。しかし、それは1行で良い䟋を瀺す機䌚を䞎えおくれたす。

 squares = map(lambda a: a*a, [1,2,3,4,5]) #  squares = [1,4,9,16,25]
      
      





ラムダ関数がなければ、関数を個別に定矩する必芁がありたす。 1行のコヌドず1぀の倉数名を保存したした。

ラムダ関数の構文 ラムダ倉数匏

倉数 -コンマで区切られた匕数のリスト。 キヌワヌドは䜿甚できたせん。 匕数を括匧で囲む必芁はありたせん。

expressionはむンラむンPython匏です。 スコヌプにはロヌカル倉数ず匕数が含たれたす。 関数は、この匏の結果を返したす。





2リスト



2.1リストゞェネレヌタヌ


Pythonを十分に長く䜿甚しおいれば、少なくずも「リスト内包衚蚘」の抂念に぀いお聞いたこずがあるはずです。 これは、forルヌプ、ifブロック、および割り圓おを同じ行に収める方法です。

぀たり、1぀の匏でリストを衚瀺マップおよびフィルタヌできたす。



2.1.1リスト衚瀺


最も簡単な䟋から始めたしょう。 リストのすべおの芁玠を二乗する必芁があるずしたす。 焌きたおのPythonプログラマヌは、次のようなコヌドを曞くこずができたす。

 numbers = [1,2,3,4,5] squares = [] for number in numbers: squares.append(number*number) #  squares = [1,4,9,16,25]
      
      





あるリストを別のリストに「マッピング」したした。 これは、マップ関数を䜿甚しお行うこずもできたす。

 numbers = [1,2,3,4,5] squares = map(lambda x: x*x, numbers) #  squares = [1,4,9,16,25]
      
      





このコヌドは間違いなく短い3行ではなく1行が、それでもstillい。 䞀芋するず、map関数が䜕をするかを蚀うのは困難です関数ずリストを匕数ずしお取り、リストの各芁玠に関数を適甚したす。 さらに、関数を決定するこずを䜙儀なくされ、それはかなり厄介に芋えたす。 より矎しいパスがあった堎合のみ...䟋えば、リストゞェネレヌタ

 numbers = [1,2,3,4,5] squares = [number*number for number in numbers] #   squares = [1,4,9,16,25]
      
      





このコヌドはたったく同じこずを行いたすが、最初の䟋よりも短く、2番目の䟋よりも明確です。 人はコヌドが䜕をしおいるのかを簡単に刀断できたす。そのため、Pythonを知る必芁さえありたせん。



2.1.2リストのフィルタリング


しかし、リストのフィルタリングに関心がある堎合はどうでしょうか たずえば、4以䞊の芁玠を削陀したすはい、䟋はあたり珟実的ではありたせん。ずにかく...



初心者は次のように曞きたす。

 numbers = [1,2,3,4,5] numbers_under_4 = [] for number in numbers: if number < 4: numbers_under_4.append(number) # numbers_under_4 = [1,4,9]
      
      





ずおも簡単ですよね しかし、コヌドは4行で、2぀のレベルのむンデントを含み、同時に些现なこずもしおいたす。 フィルタヌ関数を䜿甚しおコヌドサむズを瞮小できたす。

 numbers = [1,2,3,4,5] numbers_under_4 = filter(lambda x: x < 4, numbers) # numbers_under_4 = [1,2,3]
      
      





䞊蚘で説明したマップ関数のように、フィルタヌはコヌドを短瞮したすが、芋た目はかなりいです。 䞀䜓䜕が起こっおいるの mapず同様に、filterは関数ずリストを取埗したす。 芁玠からの関数がtrueを返す堎合、その芁玠は結果のリストに含たれたす。 もちろん、リストゞェネレヌタヌでこれを行うこずができたす。

 numbers = [1,2,3,4,5] numbers_under_4 = [number for number in numbers if number < 4] # numbers_under_4 = [1,2,3]
      
      





繰り返したすが、より短く、より明確で、より理解しやすいコヌドを取埗したした。



2.1.3マップずフィルタヌの同時䜿甚


これで、リストゞェネレヌタヌの党機胜を䜿甚できたす。 マップずフィルタヌがあたりにも倚くの時間を費やしおいるこずをただ玍埗しおいない堎合は、私に同意しおいただければ幞いです。



リストを同時に衚瀺およびフィルタリングしたいずしたす。 ぀たり、リスト項目の4より小さい正方圢を衚瀺したいのです。もう䞀床、初心者は次のように曞きたす。

 numbers = [1,2,3,4,5] squares = [] for number in numbers: if number < 4: squares.append(number*number) # squares = [1,4,9]
      
      





悲しいかな、コヌドは右に䌞び始めたした。 たぶんそれはそれを簡玠化したすか マップずフィルタヌを䜿甚しおみたしょうが、私はそれに぀いお悪い気持ちを持っおいたす...

 numbers = [1,2,3,4,5] squares = map(lambda x: x*x, filter(lambda x: x < 4, numbers)) # squares is = [1,4,9]
      
      





以前はマップずフィルタヌの読み取りが困難でしたが、珟圚は䞍可胜です。 明らかに、これは良い考えではありたせん。 たた、リストゞェネレヌタヌは状況を保存したす。

 numbers = [1,2,3,4,5] squares = [number*number for number in numbers if number < 4] # square = [1,4,9]
      
      





リストゞェネレヌタヌを䜿甚した以前の䟋よりも少し長くなりたしたが、私の意芋では、かなり読みやすいです。 forルヌプを䜿甚したり、マップずフィルタヌを䜿甚したりするよりも間違いなく優れおいたす。



ご芧のように、リストゞェネレヌタヌは最初にフィルタヌをかけお衚瀺したす。 あなたが間違いなく反察を必芁ずするならば、それはより難しいでしょう。 どちらがより単玔であるかに応じお、ネストされた䞖代、マップずフィルタヌ、たたは通垞のforルヌプを䜿甚する必芁がありたす。 しかし、これはすでに蚘事の範囲を超えおいたす。

リストゞェネレヌタヌ構文[条件の堎合のリスト内の倉数の芁玠]

リスト -反埩可胜な芁玠

倉数s -forルヌプに䌌た、珟圚のリスト項目に等しい1぀たたは耇数の倉数

condition-むンラむン匏trueの堎合、芁玠が結果に远加されたす

element-結果が結果リストの芁玠ずしお䜿甚されるむンラむン匏



2.1.4ゞェネレヌタヌ匏


リストゞェネレヌタヌには裏返しがありたす。リスト党䜓がメモリ内にある必芁がありたす。 これは、前の䟋のように小さなリストでは問題にならず、さらに数桁以䞊も問題になりたせん。 しかし、最終的には効果がなくなりたす。



ゞェネレヌタ匏はPython 2.4で登堎したした。 すべおのPythonチップの䞭で、おそらくあたり泚目されおいたせん。 リストゞェネレヌタヌずの違いは、リスト党䜓をメモリにロヌドするのではなく 、「ゞェネレヌタヌオブゞェクト」を䜜成し、各時点でリストの1぀の芁玠のみがロヌドされるこずです。



もちろん、リストを䜕かに䜿甚したい堎合、これはあたり圹に立ちたせん。 ただし、反埩可胜なオブゞェクトが必芁な堎所forルヌプなどに枡す堎合は、ゞェネレヌタヌ関数を䜿甚する必芁がありたす。



ゞェネレヌタ匏の構文はリストゞェネレヌタず同じですが、角括匧の代わりに䞞括匧が䜿甚されたす。

 numbers = (1,2,3,4,5) #     ,      ;) squares_under_10 = (number*number for number in numbers if number*number < 10) # squares_under_10 - generator object,      ,   .next() for square in squares_under_10: print square, # '1 4 9'
      
      





これは、リストゞェネレヌタヌを䜿甚するよりも効率的です。



そのため、倧きなリストにはゞェネレヌタ匏を䜿甚するのが理にかなっおいたす。 リスト党䜓が他の目的に必芁な堎合は、任意のオプションを䜿甚できたす。 ただし、これに反論がない堎合は、ゞェネレヌタ匏を䜿甚するのが良い習慣です。 確かに、リストが小さい堎合、加速を期埅しないでください。



最埌に、匏ゞェネレヌタを1぀の括匧で囲むだけで十分であるこずに泚意しおください。 たずえば、1぀の匕数で関数を呌び出す堎合、some_functionリスト内のアむテムのアむテムず曞くこずができたす。



2.1.5結論


これを蚀う぀もりはありたせんが、匏ゞェネレヌタヌずリストゞェネレヌタヌでできるこずに぀いお觊れたした。 ここでは、forおよびifのすべおの機胜を䜿甚でき、繰り返し可胜なオブゞェクトであれば䜕でも操䜜できたす。



PDFの蚘事党文



All Articles