Python文法の精妙な10の知識点(B文法を装う)

10688 ワード

Pythonは簡単な思想を表す言語で、文法は比較的簡単で、使いやすいです。しかし、これでPythonの文法のすばらしさと深さを小视すると、大间违いです。本文はPythonの文法の精妙な10の知識点を精選し、詳細な実例コードを添付します。もし実戦で解け合い、活用できれば、コードをより精錬し、効率的にすると同時に、コードBの格を大幅に向上させ、より成熟したように見え、より優雅に読むことができます。
1.for-else
なんですか?ifとelseがオリジナルじゃないですか?いいえ、知らないかもしれません。elseは二股を踏むやつです。forとelseもペアです。しかも合法です。十大はB文法を詰めて、for-elseは絶対に南に湾がないと言えます!信じません。どうぞご覧ください

>>> for i in [1,2,3,4]:
	print(i)
else:
	print(i, '  else')
	
1
2
3
4
4   else
forとelseの間に第三者if補足があれば、forとelseの関係にも影響しません。forのレベルはifより高いので、elseはまた一つの権力者です。ifがあるかどうか、if条件を満たす文を実行したかどうかは全然気にしません。elseの目にはforしかないです。forが順調に実行されれば、elseは尻が揺れるように走ります。

>>> for i in [1,2,3,4]:
	if i > 2:
		print(i)
else:
	print(i, '  else')

3
4
4   else
では、どうやってforとelseの友達を分解しますか?forループがbreak文で中断された場合のみ、else文をスキップします。

>>> for i in [1,2,3,4]:
	if i>2:
		print(i)
		break
else:
	print(i, '  else')

3
2.一つの星(*)と二つの星(*)
発見しましたか?星(*)は本当に不思議なシンボルです。考えてみます。それがないです。C言語には何か面白いものがありますか?それと同じように、Pythonがあるからこそ、このような姿態が多く、容姿が美しく、楚々としていて感動的です。Python関数はデフォルトパラメータと可変パラメータをサポートしています。一つの星は数に制限されない単一の値パラメータを表しています。二つの星は数に制限されないキーパッドのパラメータを表しています。
例を挙げて説明しましょう。一つの関数を設計して、複数の入力値の和を返します。これらの入力値をリスト関数にしてもいいですが、この方法は星一つの可変パラメータを使って優雅に来たことがありません。

>>> def multi_sum(*args):
	s = 0
	for item in args:
		s += item
	return s

>>> multi_sum(3,4,5)
12
Python関数は、固定パラメータ、標準パラメータ、シングル値(一つの星)の可変パラメータ、キーパッド対(二つの星)の可変パラメータを同時に全部または部分的に使用することができます。使用する時は、上記の順序で書かなければなりません。

>>> def do_something(name, age, gender=' ', *args, **kwds):
	print('  :%s,  :%d,  :%s'%(name, age, gender))
	print(args)
	print(kwds)

>>> do_something('xufive', 50, ' ', 175, 75, math=99, english=90)
  :xufive,  :50,  : 
(175, 75)
{'math': 99, 'english': 90}
また、一つの星と二つの星はリスト、元のグループ、辞書の解凍にも使えます。C言語のように見えます。

>>> a = (1,2,3)
>>> print(a)
(1, 2, 3)
>>> print(*a)
1 2 3
>>> b = [1,2,3]
>>> print(b)
[1, 2, 3]
>>> print(*b)
1 2 3
>>> c = {'name':'xufive', 'age':51}
>>> print(c)
{'name': 'xufive', 'age': 51}
>>> print(*c)
name age
>>> print('name:{name}, age:{age}'.format(**c))
name:xufive, age:51
3.三元表現
C/C++のプログラマをよく知っています。pythonを始めた時、きっと古典的な三元のオペレータを懐かしく思います。同じ考えを表現したいので、pythonで書くのはもっと面倒くさいようです。たとえば:

>>> y = 5
>>> if y < 0:
	print('y     ')
else:
	print('y      ')

y      
実は、pythonは三元表現を支持していますが、ちょっとおかしいです。私達山東人の話のようです。例えば、山東の人が一番好きです。バックパッキングで行きましょう。雨が降らないなら。雨が降ったら、自習室に行きます。三元表現に訳せば、
球技に行きましょう。雨が降らないから、自習室に行きます。
三元表現の具体的な使い方を見てみましょう。

>>> y = 5
>>> print('y     ' if y < 0 else 'y      ')
y      
pythonの3元表現は、値を付けるためにも使用できます。

>>> y = 5
>>> x = -1 if y < 0 else 1
>>> x
1
4.with-as
withという言葉は英語では翻訳が難しくないですが、Pythonの文法ではどうやって翻訳すればいいのか分かりません。大体コンテキスト管理協議です。初心者として、withの様々な方法や仕組みに関心を持たなくても、その応用シーンを知るだけでいいです。with文は事前に準備が必要で、後で処理する必要があるタスクに適合しています。例えば、ファイル操作は、まずファイルを開けて、操作が完了したら、ファイルを閉じる必要があります。withを使わない場合、ファイルの操作は通常このようになります。

fp = open(r"D:\jb51\Column\temp\mpmap.py", 'r')
try:
 contents = fp.readlines()
finally:
 fp.close()
with-asを使うと優雅になります。

>>> with open(r"D:\jb51\Column\temp\mpmap.py", 'r') as fp:
	contents = fp.readlines()
5.リスト導出式
様々な奇妙な構文の中で、リスト導出式の使用頻度は最も高いはずであり、コードの簡略化効果に対しても非常に顕著である。例えば、リストの各要素の平方を求めて、通常はこのように書くべきです。

>>> a = [1, 2, 3, 4, 5]
>>> result = list()
>>> for i in a:
	result.append(i*i)

>>> result
[1, 4, 9, 16, 25]
リストガイドを使うと、楽に見えます。

>>> a = [1, 2, 3, 4, 5]
>>> result = [i*i for i in a]
>>> result
[1, 4, 9, 16, 25]
実は、導き出す式はリストだけではなく、辞書、集合、タプルなどのオブジェクトにも対応しています。興味があれば、自分で研究してもいいです。私はブログ「一行のPythonコードは何の狂気じみた機能を実現できますか?」を持っています。その中の例はリストガイド式で実現されました。
6.リスト索引の各種の操作
Pythonは負の整数を行列のインデックスとして導入しています。これは間違いなく喜びの一つです。考えてみてください。C/C++の中で、最後の要素を配列したいです。まず配列長を取って、インデックスを作ってから、思考の一貫性に深刻に影響します。Python言語が成功したのは、多くの要因の中でリスト操作の便利さが無視できないと思います。見てください:

>>> a = [0, 1, 2, 3, 4, 5]
>>> a[2:4]
[2, 3]
>>> a[3:]
[3, 4, 5]
>>> a[1:]
[1, 2, 3, 4, 5]
>>> a[:]
[0, 1, 2, 3, 4, 5]
>>> a[::2]
[0, 2, 4]
>>> a[1::2]
[1, 3, 5]
>>> a[-1]
5
>>> a[-2]
4
>>> a[1:-1]
[1, 2, 3, 4]
>>> a[::-1]
[5, 4, 3, 2, 1, 0]
これらはよく知っていて、いつも使っています。次の使い方はきっと不思議です。

>>> a = [0, 1, 2, 3, 4, 5]
>>> b = ['a', 'b']
>>> a[2:2] = b
>>> a
[0, 1, 'a', 'b', 2, 3, 4, 5]
>>> a[3:6] = b
>>> a
[0, 1, 'a', 'a', 'b', 4, 5]
7.ラダ関数
lambadaは大きく聞こえますが、実は匿名関数です。匿名関数のアプリケーションシーンは何ですか?匿名関数を定義するところだけにこの関数を使うので、他のところでは使えないので、阿猫犬のような名前を付ける必要はありません。以下は合計の匿名関数です。入力パラメータは2つあります。xとyは関数体はx+yです。returnキーワードを省略しました。

>>> lambda x,y: x+y
<function <lambda> at 0x000001B2DE5BD598>
>>> (lambda x,y: x+y)(3,4) #           ,              
匿名関数は一般に単独では使用されず、他の方法に協力して内蔵されたアルゴリズムまたは判定条件を提供する。例えば、並べ替え関数sortedを使って多次元配列または辞書を並べ替える場合、並べ替え規則を指定できます。

>>> a = [{'name':'B', 'age':50}, {'name':'A', 'age':30}, {'name':'C', 'age':40}]
>>> sorted(a, key=lambda x:x['name']) #      
[{'name': 'A', 'age': 30}, {'name': 'B', 'age': 50}, {'name': 'C', 'age': 40}]
>>> sorted(a, key=lambda x:x['age']) #      
[{'name': 'A', 'age': 30}, {'name': 'C', 'age': 40}, {'name': 'B', 'age': 50}]
もう一つの配列要素の平方を求める例を挙げます。今回はmap関数を使います。

>>> a = [1,2,3]
>>> for item in map(lambda x:x*x, a):
	print(item, end=', ')

1, 4, 9, 
8.yieldおよびジェネレータとサブジェネレータ
yieldという言葉は、本当に訳しにくいです。辞書を引いても役に立ちません。私は思い切って「一愛得」と読んで、外来語と言えるでしょう。yieldを理解するには、まずGEnerator(ジェネレータ)を理解しなければなりません。generatorを知るには、まずiteratorを知っておく必要があります。ハハハ、目まいがしましたか?もういいです。やはり白話をします。
さて、py 2時代はランゲ()がlistに戻ってきましたが、ランゲ(100000万円)の場合はメモリがたくさん消費されますので、py 2はまた一つのxrange()を作ってこの問題を解決しました。py 3はxrange()だけ残していますが、range()と書きます。xrange()が戻ってきたのはローズマリーです。リストのように遍歴できますが、メモリはあまり使われていません。GEnerator(ジェネレータ)は特殊なローズマリーで、一回しか経たないです。遍歴が終わると、自動的に消えてしまいます。つまり、サブジェネレータでもジェネレータでも、リストの使用を避けるためにメモリを節約します。では、どうやってサブジェネレータとジェネレータを手に入れますか?
pythonは反復関数iterを内蔵しています。

>>> a = [1,2,3]
>>> a_iter = iter(a)
>>> a_iter
<list_iterator object at 0x000001B2DE434BA8>
>>> for i in a_iter:
	print(i, end=', ')

1, 2, 3,
yieldはジェネレータを作るためのものです。たとえば、私たちは関数を書きたいです。0から正の整数までのすべての整数の平方を返します。伝統的なコードの書き方はこうです。

>>> def get_square(n):
	result = list()
	for i in range(n):
		result.append(pow(i,2))
	return result

>>> print(get_square(5))
[0, 1, 4, 9, 16]
しかし、1億以内のすべての整数の平方を計算すれば、この関数のメモリコストは非常に大きくなります。これはyieldが活躍できます。

>>> def get_square(n):
	for i in range(n):
		yield(pow(i,2))

>>> a = get_square(5)
>>> a
<generator object get_square at 0x000001B2DE5CACF0>
>>> for i in a:
	print(i, end=', ')

0, 1, 4, 9, 16, 
もう一度遍歴したら、出力はありません。
9.飾り器
ローズマリーとジェネレータが分かりました。これはまた装飾器です。Pythonはどうしてこんなに多くの器がありますか?確かにPythonは多くの武器を提供してくれます。装飾器は最も強力な武器の一つです。装飾器はとても強いです。ここで必要な角度から簡単な例を使って装飾器の使い方と製造技術を説明します。
もし私たちが複数の関数を定義する必要があるならば、各関数が動作する時にこの関数の実行時間が長いことを示して、解決策はたくさんあります。例えば、各関数を呼び出す前にタイムスタンプを読んで、各関数の運転が終わったらタイムスタンプを読んで、差を求めてもいいです。各関数内の開始位置と終了位置にタイムスタンプを読み取り、最後に差分を求めることもできます。しかし、この二つの方法は装飾器を使うほど簡単で優雅ではありません。次の例は、この点をよく示しています。

>>> import time
>>> def timer(func):
	def wrapper(*args,**kwds):
		t0 = time.time()
		func(*args,**kwds)
		t1 = time.time()
		print('  %0.3f'%(t1-t0,))
	return wrapper

>>> @timer
def do_something(delay):
	print('  do_something  ')
	time.sleep(delay)
	print('  do_something  ')

	
>>> do_something(3)
  do_something  
  do_something  
  3.077
timer()は私達が定義した装飾関数です。@を使って、どんな関数にも付けます。something)定義する前に、新しい定義の関数を装飾器関数の入力パラメータとして扱うことになります。ドゥドゥを実行しますsomething関数は、timer(dou)を実行したと理解できます。something。細部は複雑ですが、このような理解は偏りが大きくなく、装飾器の製作と使用を把握しやすいです。
10.巧はアサルトを断言する
断言すると、宣言式のブール値は本当に判定されなければならない。そうでなければ、AsertionErr異常をトリガする。厳密には、astertはデバッグ手段であり、生産環境では使わないが、これは私達が断言して特定の機能を実現することに影響しない。例えば、パラメータを入力するフォーマット、タイプの検証など。

>>> def i_want_to_sleep(delay):
	assert(isinstance(delay, (int,float))), '             '
	print('    ')
	time.sleep(delay)
	print('   ')

	
>>> i_want_to_sleep(1.1)
    
   
>>> i_want_to_sleep(2)
    
   
>>> i_want_to_sleep('2')
Traceback (most recent call last):
 File "<pyshell#247>", line 1, in <module>
 i_want_to_sleep('2')
 File "<pyshell#244>", line 2, in i_want_to_sleep
 assert(isinstance(delay, (int,float))), '             '
AssertionError:              
Pythonの文法の素晴らしい10の知識点についての関連記事をここまで紹介します。どうぞよろしくお願いします。