経験豊富なプログラマーが使用する8つのPythonトリック

画像



まだ見たことがないと思う、8つの優雅なPythonのトリックを以下に示します。これらのトリックをPythonコードに適用して、コードをより簡潔で高性能にします!



1.複数のキーによるオブジェクトの並べ替え



次の辞書リストをソートしたいとします。



people = [
{ 'name': 'John', "age": 64 },
{ 'name': 'Janet', "age": 34 },
{ 'name': 'Ed', "age": 24 },
{ 'name': 'Sara', "age": 64 },
{ 'name': 'John', "age": 32 },
{ 'name': 'Jane', "age": 34 },
{ 'name': 'John', "age": 99 },
]


ただし、名前や年齢だけで並べ替えるのではなく、両方のフィールドで並べ替えたいと考えています。SQLでは、これは次のようなクエリになります。



SELECT * FROM people ORDER by name, age


ソート関数がソートの永続性を提供するというPythonの保証のおかげで、実際にはこの問題に対する非常に単純な解決策がありますつまり、比較される要素は元の順序を維持します。



名前と年齢でソートするには、次のようにします。



import operator
people.sort(key=operator.itemgetter('age'))
people.sort(key=operator.itemgetter('name'))


順序を変更した方法に注意してください。まず、年齢で並べ替えてから、名前で並べ替えます。助けoperator.itemgetter()借りて、リストの各辞書から年齢と名前のフィールドを取得します。



これにより、必要な結果が得られます。



[
 {'name': 'Ed',   'age': 24},
 {'name': 'Jane', 'age': 34},
 {'name': 'Janet','age': 34},
 {'name': 'John', 'age': 32},
 {'name': 'John', 'age': 64},
 {'name': 'John', 'age': 99},
 {'name': 'Sara', 'age': 64}
]


名前が最初にソートされ、名前が一致する場合は年齢がソートされます。したがって、すべてのジョーンズは年齢別にグループ化されています。



インスピレーションの源-StackOverflowからの質問



2.リストの包含(リストジェネレータ)



リストの包含は、リストの作成に使用される醜いループを置き換えることができます。リスト包含の基本的な構文:



[ expression for item in list if conditional ]


リストに一連の数値を入力する非常に簡単な例:



mylist = [i for i in range(10)]
print(mylist)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


また、式を使用できるため、いくつかの計算も実行できます。



squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]


または、外部関数を呼び出します。



def some_function(a):
    return (a + 5) / 2
    
my_formula = [some_function(i) for i in range(10)]
print(my_formula)
# [2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]


最後に、「if」を使用してリストをフィルタリングできます。この場合、2で割り切れる値のみを保存します:



filtered = [i for i in range(20) if i%2==0]
print(filtered)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]


3.オブジェクトのメモリ使用量を確認します



sys.getsizeof()を使用して、オブジェクトのメモリ使用量を確認できます。



import sys

mylist = range(0, 10000)
print(sys.getsizeof(mylist))
# 48


うわー...待って...なぜこの巨大なリストがちょうど48バイトなのですか?

これは、範囲関数がリストのようにのみ動作するクラスを返すためです。範囲は、実際の数値のリストよりもはるかにメモリを消費しません。

リストの包含を使用して、同じ範囲から実際の数のリストを作成することを確認できます。



import sys

myreallist = [x for x in range(0, 10000)]
print(sys.getsizeof(myreallist))
# 87632


したがって、をいじってsys.getsizeof()みる、Pythonとメモリ使用量について詳しく知ることができます。



4.データクラス



バージョン3.7以降、Pythonはデータクラスを提供しています。複数の値や辞書を返すなど、通常のクラスや他の代替手段に比べていくつかの利点があります:



  • データクラスには最小限のコードが必要
  • データクラスを比較できるのは __eq__
  • デバッグのためにデータクラスを簡単に推測できます。 __repr__
  • データクラスにはテープヒントが必要です。これにより、エラーの可能性が減少します。


動作中のデータクラスの例を次に示します。



from dataclasses import dataclass

@dataclass
class Card:
    rank: str
    suit: str
    
card = Card("Q", "hearts")

print(card == card)
# True

print(card.rank)
# 'Q'

print(card)
Card(rank='Q', suit='hearts')


詳細なガイドはここにあります



5. attrsパッケージ



データクラスの代わりに、attrsを使用できます選択する理由は2つありますattrs



  • 3.7より古いバージョンのPythonを使用している
  • もっとオプションが欲しい


パッケージattrsは、CPython 2.7とPyPyを含むすべての主要なPythonバージョンをサポートします。attrs通常のデータクラスで提供される追加属性の一部は、バリデーターとコンバーターです。コード例を見てみましょう:



@attrs
class Person(object):
    name = attrib(default='John')
    surname = attrib(default='Doe')
    age = attrib(init=False)
    
p = Person()
print(p)
p = Person('Bill', 'Gates')
p.age = 60
print(p)

# Output: 
#   Person(name='John', surname='Doe', age=NOTHING)
#   Person(name='Bill', surname='Gates', age=60)


著者はattrs実際にデータクラスを導入したPEPで作業しました。データクラスは意図的により簡単に(理解しやすく)保存されますが、attrsは必要な関数の完全なセットを提供します!



その他の例は、attrsサンプルページにあります



6.辞書を組み合わせる(Python 3.5以降)



Python 3.5以降では、辞書を組み合わせる方が簡単です。



dict1 = { 'a': 1, 'b': 2 }
dict2 = { 'b': 3, 'c': 4 }
merged = { **dict1, **dict2 }
print (merged)
# {'a': 1, 'b': 3, 'c': 4}


キーが重複している場合、最初の辞書のキーが上書きされます。



Python 3.9では、辞書を組み合わせるとさらにきれいになります。上記のPython 3.9のマージは、次のように書き直すことができます。



merged = dict1 | dict2


7.最も一般的な値を検索します



リストまたは行で最も一般的な値を見つけるには:



test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
print(max(set(test), key = test.count))
# 4


これが機能する理由を理解していますか?これを読む前に自分で理解してみてください。



あなたも試しましたよね?とにかく教えてあげましょう。



  • max()リストの最大値を返します。引数keyは、単一の引数関数を使用して、ソート順をカスタマイズします(この場合はtest.count)。関数は、イテラブルの各要素に適用されます。
  • test.count-組み込みリスト機能。引数を取り、その引数の出現回数をカウントします。したがって、test.count(1)2をtest.count(4)返し、4 返します。
  • set(test) テストからすべての一意の値を返すため、{1、2、3、4}


したがって、この1行のコードでは、であるテストのすべての一意の値を受け入れます{1, 2, 3, 4}次に、maxそれらに関数を適用しlist.count、最大値を返します。



そして、いいえ-私はこのワンライナーを発明しませんでした。



更新:多くのコメンテーターは、これを行うためのより効率的な方法があることを正しく指摘しています:



from collections import Counter
Counter(test).most_common(1)
# [4: 4]


8.複数の値を返す



Pythonの関数は、辞書、リスト、またはクラスなしで複数の変数を返すことができます。それはこのように動作します:



def get_user(id):
    # fetch user from database
    # ....
    return name, birthdate

name, birthdate = get_user(4)


これは、戻り値の数が限られている場合には問題ありません。ただし、3つの値を超えるものはすべて(データ)クラスに配置する必要があります。



画像



SkillFactoryの有料オンラインコースを受講して、スキルと給与の注目の職業をゼロから取得する方法の詳細をご覧ください。











All Articles