Pythonでプログラミングするときの注意事項

Zen Python





言語を取り巻く文化を学ぶことで、最高のプログラマーに一歩近づくことができます。 Zen of Pythonをまだ読んでいない場合は、Pythonインタープリターを開いてimport thisを入力してください 。 リスト内の各アイテムについては、 ここで例を見つけることができます



私の注意が惹かれたら:



isいよりも美しい



更新:この記事については、 Hacker Newsで多くの議論がありました。 それらからのいくつかの修正。



数値のリストを受け取り、2で割った偶数のみを返す関数を提供します。



#----------------------------------------------------------------------- halve_evens_only = lambda nums: map(lambda i: i/2, filter(lambda i: not i%2, nums)) #----------------------------------------------------------------------- def halve_evens_only(nums): return [i/2 for i in nums if not i % 2]
      
      







Pythonで非常に単純なことを覚えてください





2つの変数の値の交換:



  a, b = b, a
      
      







スライスのステップ引数。 例:



  a = [1,2,3,4,5] >>> a[::2] # iterate over the whole list in 2-increments [1,3,5]
      
      







特殊なケースx [::-1]は、 x.reverse()を表現する手段です。



  >>> a[::-1] [5,4,3,2,1]
      
      







更新: x.reverse()はリストを反転し、スライスを使用するとこれを実行できることに注意してください。



  >>> x[::-1] [5, 4, 3, 2, 1] >>> x[::-2] [5, 3, 1]
      
      











  def function(x, l=[]): # Don't do this def function(x, l=None): # Way better if l is None: l = []
      
      







更新:理由を説明しなかったことを理解しています。 Fredrik Lundhによる記事を読むことをお勧めします。 要するに、このデザインは時々見られます。 「デフォルト値は、 defが実行用に宣言されている場合にのみ、常に計算されます。」







iteritemsジェネレーターを使用するため、非常に大きなリストを操作する場合に適しています。



  d = {1: "1", 2: "2", 3: "3"} for key, val in d.items() # builds complete list when called. for key, val in d.iteritems() # calls values only when requested.
      
      







これは、 要求されたときにxrangeが値のみを呼び出す場合のrangeおよびxrangeに似ています



更新: iteritemsiterkeysitervaluesは Python 3.xから削除されていることに注意してください。 dict.keys()dict.items()およびdict.values()は、リストの代わりにビューを返しますdocs.python.org/release/3.1.5/whatsnew/3.0.html#views-and-iterators-instead-of-lists







しないでください:



  if type(s) == type(""): ... if type(seq) == list or \ type(seq) == tuple: ...
      
      







より良い:



  if isinstance(s, basestring): ... if isinstance(seq, (list, tuple)): ...
      
      







これを行うべきではない理由: stackoverflow.com/a/1549854/504262



unicodeが strと一致するかどうかを確認できるため、 strではなくbasestringを使用していることに注意してください。 例:



  >>> a=u'aaaa' >>> print isinstance(a, basestring) True >>> print isinstance(a, str) False
      
      







これは、Pythonバージョン<3.0には、 strunicodeの 2つの文字列タイプがあるためです。



  object | | basestring / \ / \ str unicode
      
      











Pythonにはさまざまなタイプのデータコンテナがあり、さまざまなケースで基本的なリスト辞書に代わる最良の選択肢です。



ほとんどの場合、これらは使用されます:



更新:私はほとんどがこれを使用していないことを知っています。 私の側の不注意。 これを書く人もいます:



  freqs = {} for c in "abracadabra": try: freqs[c] += 1 except: freqs[c] = 1
      
      







より良いと言う人もいるかもしれません:



  freqs = {} for c in "abracadabra": freqs[c] = freqs.get(c, 0) + 1
      
      







むしろ、タイプdefaultdictのコレクションを使用します。



  from collections import defaultdict freqs = defaultdict(int) for c in "abracadabra": freqs[c] += 1
      
      







その他のコレクション



  namedtuple() # factory function for creating tuple subclasses with named fields deque # list-like container with fast appends and pops on either end Counter # dict subclass for counting hashable objects OrderedDict # dict subclass that remembers the order entries were added defaultdict # dict subclass that calls a factory function to supply missing values
      
      







更新:Hacker Newsに関するいくつかのコメントで述べたように、 defaultdictの代わりにCounterを使用できます。



  >>> from collections import Counter >>> c = Counter("abracadabra") >>> c['a'] 5
      
      











  __eq__(self, other) # Defines behavior for the equality operator, ==. __ne__(self, other) # Defines behavior for the inequality operator, !=. __lt__(self, other) # Defines behavior for the less-than operator, <. __gt__(self, other) # Defines behavior for the greater-than operator, >. __le__(self, other) # Defines behavior for the less-than-or-equal-to operator, <=. __ge__(self, other) # Defines behavior for the greater-than-or-equal-to operator, >=.
      
      







他にも多くの魔法の方法があります。







  x = 3 if (y == 1) else 2
      
      







このコードは、「 y = 1の場合は3xに割り当て、それ以外の場合は2xに割り当てます」というように聞こえます。 より複雑なものがある場合、これを適用することもできます。



  x = 3 if (y == 1) else 2 if (y == -1) else 1
      
      







ある時点では行き過ぎです。



任意の式でif ... else式を使用できることに注意してください。 例:



  (func1 if y == 1 else func2)(arg1, arg2)
      
      







y = 1の場合はfunc1が呼び出さ 、そうでない場合はfunc2が呼び出さます。 どちらの場合でも、対応する関数は引数arg1arg2で呼び出されます。



同様に、以下も当てはまります。



  x = (class1 if y == 1 else class2)(arg1, arg2)
      
      







class1とclass2はクラスです。







更新:ハッカーニュースのコメンテーターの一人は、「省略記号を使用してすべての要素を取得すると、「目標を達成する唯一の方法」の原則に違反します。 標準指定は[:]です。」 私は彼に同意します。 stackoverflowでの NumPyのベスト使用例:



省略記号は、多次元データ構造をスライスするために使用されます。



この状況では、これは、すべての次元で多次元スライスを展開する必要があることを意味します。



例:



  >>> from numpy import arange >>> a = arange(16).reshape(2,2,2,2)
      
      







これで、次数2x2x2x2の4次元マトリックスができました。 4次元の最初のすべての要素を選択するには、省略記号を使用できます。



  >>> a[..., 0].flatten() array([ 0, 2, 4, 6, 8, 10, 12, 14])
      
      







これは次の記述と同等です。



  >>> a[:,:,:,0].flatten() array([ 0, 2, 4, 6, 8, 10, 12, 14])
      
      







以前のオファー。



クラスを作成するときに、 __ getitem__を使用して、クラスオブジェクトを辞書のように動作させることができます。 このクラスを例に取ります。



  class MyClass(object): def __init__(self, a, b, c, d): self.a, self.b, self.c, self.d = a, b, c, d def __getitem__(self, item): return getattr(self, item) x = MyClass(10, 12, 22, 14)
      
      







__getitem__によりオブジェクトxのaを x ['a']として取得できます。 これはおそらく既知の事実です。



このオブジェクトは Pythonスライスdocs.python.org/library/stdtypes.html#bltin-ellipsis-objectを拡張するために使用されるため、以下を追加する場合:



  def __getitem__(self, item): if item is Ellipsis: return [self.a, self.b, self.c, self.d] else: return getattr(self, item)
      
      







x [...]を使用して、すべての要素のリストを取得できます。



  >>> x = MyClass(11, 34, 23, 12) >>> x[...] [11, 34, 23, 12]
      
      












PS





これはSatyajit Ranjeevの投稿の翻訳です-「 Pythonでコーディングする際に覚えておくべきことただし、転送ハブに0.5カルマがなく、下書きを保存できないため、そのまま投稿します。 PMでの翻訳とスペルに関するコメントをすべて送信してください。



All Articles