Pythonアルゴリズムの基本をクリア

28672 ワード

Python基本文法

  • タイプのヒント
  • 計算(リスト統合、Dict Comp.、Set Comp.、Generator Expression)
  • 発電機、range
  • 複数の関数(列挙、除算演算子、印刷および文字列フォーマット、pass、locals、スタイルガイド)
  • 参照時の注意点
  • リスト、set、dictのデフォルト演算子
  • 1.タイプヒント


    Pythonはダイナミックタイプ言語(interpreter言語)であるが、大規模なプロジェクトでも可読性を向上させるタイプのヒント機能がある.(ただし、これは強制的な約束ではありません.ユーザーはタイププロンプトを表示するか、正しく割り当てられていない可能性があります.mypyをインストールし、実行前にチェックする機能を使用できます.)

    2.計算(リスト、Dict Comp.、Set Comp.、Generator Expression)


    宣言、繰り返し、条件文(リスト、コレクション、ディック宣言など)では、コンストラクション関数内で簡単に定義できます.
    
    # 반복 및 조건문
    [n*2 for n in range(1, 10+1) if n % 2 == 1] # [2,6,10,14,18]
    
    # if문들은 and로 묶여 모두 만족하는 경우에만 실행
    [i for i in range(5) if i%2==0 if i%4==0] # [0,2,4]
    
    # if, else를 함께 쓰는 경우에는 반복문 왼쪽에
    [i if i%2==0 else 'odd' for i in range(5)] # [0,'odd',2,'odd',4]
    
    # 다중 조건문 실행결과
    [(i,j) for i in range(2) for j in range(3)] # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
    
    # 두가지 모두 동일한 실행 결과를 리턴
    [(i,j) for i in range(3) if i%2 == 0 for j in range(3)]
    [(i,j) for i in range(3) for j in range(3) if i%2 == 0]
    # [(0, 0), (0, 1), (0, 2), (2, 0), (2, 1), (2, 2)]
    
    # Set, Dict에서도 동일하게 작동한다.
    [j for i in range(3) for j in range(3)] # [0, 1, 2, 0, 1, 2, 0, 1, 2]
    {j for i in range(3) for j in range(3)} # {0, 1, 2}
    {i:j for i in range(3) for j in range(3)} # {0: 2, 1: 2, 2: 2}
    
    # 손쉽게 key와 value를 swap할 수 있다
    a = {1: 'one', 2: 'two'}
    {value:key for key,value in a.items()} # {'one': 1, 'two': 2}
    
    # Generator도 쉽게 생성할 수 있다.
    # 호출 가능한 범위를 벗어나게 되면 StopIteration 에러 발생
    gen = (x**2 for x in range(10))
    print(gen) # <generator object <genexpr> at 0x105bde5c8>
    print(next(gen)) # call 1 # 0
    print(next(gen)) # call 2 # 1
    # ...
    print(next(gen)) # call 11
    
    # Generator Expression으로 생성하는 경우에도,
    # yield로 생성하는 일반적인 경우와 똑같이 sum을 사용할 수 있다. (iterable 객체)
    gen = (x**2 for x in range(10))
    sum_of_squares = sum(gen) # 285

    3.発電機、range


    ループの繰返し動作を制御できるインスタンス形状.大量の値を生成するなどの操作に使用します.すべての値をメモリに保存し、メモリに保存せずに実行するたびに値を生成することで、メモリを大幅に節約できます.サードパーティの値はyieldでエクスポートできます.関数は終了せず、次のyieldが大きくなったときに再実行されます.
    def test_generator():
        yield 1
        yield 'string'
        yield True
    gen = test_generator()
    type(gen) # <class 'generator'>
    next(gen) # 1
    next(gen) # 'string'
    next(gen) # True
    next(gen) # StopIteration 에러 발생
    2つのオブジェクトは、それぞれ独立して動作する異なるオブジェクトです.
    h = test_generator()
    i = test_generator()
    h == i # False
    h is i # False
    next(h) # 1
    next(i) # 1
    rangeはサードパーティ方式を用いた代表的な関数である.range()を使用してrangeクラスオブジェクトを作成し、作成条件を設定し、必要に応じて数値を生成できます.次の2つの例では、100万個の数値を異なる方法で出力しますが、データ型とメモリ使用率に差があります.事前に生成されていない値は、インデックスにアクセスするとすぐに生成されるので、リストとほぼ同じ感覚を使用できます.
    a = [ n for n in range(1000000)]
    b = range(1000000)
    len(a) # 1000000
    len(b) # 1000000
    type(a) # <class 'list'>
    type(b) # <class 'range'>
    b # range(0, 1000000)
    import sys
    sys.getsizeof(a) # 8448728
    sys.getsizeof(b) # 48

    4.複数のヘルプ関数(列挙、除算演算子、印刷および文字列フォーマット、pass、localas、スタイルガイド)


    列挙():インデックスと値の同時処理
    a = [2,4,6,8]
    for idx,val in enumerate(a):
        print(idx,val)
    
    除算演算子://商に戻り、%は余剰を返します.divmodは一度にシェアと残りの部分を返します.
    5 // 3 # 1
    5 % 3 # 2
    divmod(5,3) # (1, 2)
    print:sep、endを指定できます.string formationは一緒に使うと便利です
    print("aa", "bb", "cc", sep="~~", end="@@finish@@")
    # aa~~bb~~cc@@finish@@ # 이후 줄바꿈 없이 다음 줄이 연이어서 프린트된다.
    
    idx = 3
    val = "three"
    print("{0}: {1}".format(idx,val)) # 3: three
    print(f"{idx}: {val}") # 3: three
    pass:コードのスケルトン全体をキャプチャし、後で内部関数を作成できる空の演算を返します.
    locals:locals()は、現在ローカルスキャンで定義されているすべての変数を返します.printはアルゴリズムデバッグに使用できます.pprintをpprintにインポートします.きれいなソートのローカル変数をpprint(locals()で出力できます!
    指示:パラメータの開始に指示を追加するか、次の行と混同しない
    ネーミングミーティング:推奨Snakeケース
    スタイリングガイド:不明な点はないでください.可変オブジェクトを使用し、関数の変数のデフォルト値として可変オブジェクトを使用します.真のエラーを表すには、暗黙的な方法を使用します.
    # Good
    def foo(a, b=None):
        if b is None:
            b = []
        pass
    
    def foo(a, b: Optional[Sequence] = None):
        if b is None:
            b = []
        pass
    
    if not users:
        print('no users')
    
    if foo == 0:
        self.handle_zero()
    
    if i % 10 == 0:
        self.handle_multiple_of_ten()
    
    # Bad
    def foo(a, b=[]):
        pass
    
    def foo(a, b: Mapping = {}):
        pass
    
    if len(users) == 0:  # foo != [] 등으로 체크하는 것도 비추, not users로 의미 전달 명확하게
        print('no users')
    
    if foo is not None and not foo: # 0인 것을 암시적 False 대신 정수로 처리하는 것이 명확
        self.handle_zero()
    
    if not i % 10: # 1 % 10 == 0과 같이 명시적으로 값을 비교하는 것이 좋다
        self.handle_multiple_of_ten()
    

    5.参考にするときの注意事項


    C++と他の参照との比較
    C++では、参照タイプを再割り当てしてもメモリアドレスは変わりません.逆に、Pythonは元のタイプではなく、オブジェクト-不変オブジェクトまたは可変オブジェクト-から構成されています.新しい不変オブジェクトが割り当てられている場合、新しいオブジェクトを参照するときに指すメモリアドレスが変化し、可変オブジェクトの場合、参照オブジェクトの変数も変化し、次の結果が得られます.パイソンのリストの各項目の登録アドレス値は個別に所有されています.https://del4u.tistory.com/27はgoodを説明する(new list=old list[:]またはnew list=list(old list)を使用して新しいリストを指すことができることに注意).
    ちなみにPythonの速度が遅い理由の1つは、整数型の加算を行うだけでも、CやJavaとは異なる付加演算が存在していること、例えばオブジェクトの中でタイプコードを探すなどです.
    // C++
    int a = 10;
    int &b = a;
    b = 7;
    std::cout << a << std::endl; // 7
    # python
    a = 10
    b = a
    b = 7
    print(a, id(a),id(b)) # 10, 4550522560, 4550522464
    
    a = [1, 2, 3]
    b = a
    b[2] = 5
    print(a) # [1, 2, 5], 리스트의 경우 각각이 
    isと==
    isはid()値を比較する関数であり、==は比較値の演算子である.Noneは値自体を定義しておらず、isでしか比較できません!

    6.リスト、set、dictのデフォルト演算子


    https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt部分内容