スムーズなpython

22403 ワード

スムーズなpythonには奇抜なテクニックが多く、Python標準ライブラリを最大限に利用する方法を強調しています.pythonの一般的ではないデータ型、操作、ライブラリなどを多く紹介しており、pythonを入門した後にpythonに対する認識を高めるのに役立つはずです.現在、1回読むと、いくつかの共感できる操作が記録されています.
Python内蔵シーケンスタイプの主な分類:
格納可能な要素のタイプによって、コンテナシーケンスとフラットシーケンスに分けられます.
  • 容器シーケンスは、何でも要素として中に入れることができ、別のシーケンスを含む.要素がシーケンスタイプである場合、保存されるのは参照であり、注意が必要であることに注意してください.

  • 一般的なコンテナシーケンスにはlist,tuple,array.array,collections.dequeなど.
  • 扁平配列で、格納されているのはすべて原子級元素であり、このとき格納されているのは参照ではなく値である.

  • 一般的なフラットシーケンスにはstr,bytes,bytearray,memoryview,array.arrayなど.
    シーケンスによって変更できるかどうかは、可変シーケンスと可変シーケンスに分けられます.
  • 可変シーケンス:list,bytearray,arrayを含む、追加、削除、変更などの操作が可能なシーケンス.array, collections.deque、memoryviewなど.
  • 可変シーケンス:tuple,str,bytesなどを含む上述した操作を行うことができないシーケンス.

  • 辞書の変種
    標準ライブラリcollectionsモジュールには、辞書のタイプに似た多くの変種が提供されています.
    OrderDict:このタイプはキーを追加するときに順序が保存されるので、キーの反復順序は常に一致します.
    ChainMap:このタイプでは、複数の異なるマッピングペアを収容できます.キーの検索を行うと、キーが見つかるまでオブジェクト全体として検索されます.
    Counter:このマッピングタイプは、キーに整数テクノロジーを用意し、キーを1つ追加するたびにこのカウンタを追加するので、このタイプは、ハッシュ・リスト・オブジェクトのカウントや多重セットとして使用できます.
    UserDict:このクラスは実は標準的なdictをPythonでもう一度書きました.一般に、プログラマがdictを継承して自分のdictを作成したい場合にdictの代わりに使用するために使用されます.主に原生dictを直接継承するとバグが発生するためです.
    defaultdict:見つからないキーを処理する1つの選択あるキーがマッピングにない場合、デフォルト値も得たい.これがdefaultdictであり、dictのサブクラスであり、missing法を実現している.
    dictの実現と結果
            :
                    。
        (1)    hash()   ,     __hash__()              。
        (2)      __eq__()         。
        (3)   a == b   ,  hash(a) == hash(b)    。
                           ,          id()    , 
                 。
              (      )。
                          :
        (1)             ,
        (2)                      。
          
               
                       
    

    setの実装と結果

    collections.namedtupleは、フィールド名付きメタグループと名前付きクラスを構築するために使用できます.
    名前付きメタグループを作成するには、クラス名とクラスの各フィールドの名前の2つのパラメータが必要です.後者は、複数の文字列からなる反復可能なオブジェクト、またはスペースで区切られたフィールド名からなる文字列であってもよい.
    >>> from collections import namedtuple
    >>> City = namedtuple('City', 'name country population coordinates')
    >>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) 
    >>> tokyo
    City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722,
    139.691667))
    >>> tokyo.population 
    36.933
    >>> tokyo.coordinates
    (35.689722, 139.691667)
    >>> tokyo[1]
    'JP'
    
    >>> City = namedtuple('City_Name', 'name country population coordinates')
    >>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
    >>> tokyo
    City_Name(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))

    リストが優先でない場合
  • 数字だけを含むリストが必要ならarray.arrayはlistよりも効率的です.配列サポート
  • 可変シーケンスに関する動作があり、以下を含む.pop、.义齿extend.また、配列は、ファイルからファイルを読み取る、格納するよりも高速な方法を提供する.そしてtofile.
  • set要素が存在するかどうかを確認するために最適化された
  • memoryviewは、コンテンツをコピーせずに同じ配列の異なる
  • を操作できる内蔵クラスである.
    スライス.
  • NumPyおよびSciPyによって提供される高次配列および行列動作
  • を使用する.
  • 双方向キューおよびその他の形式のキュー(collections.deque双方向キュークラス、queueクラスのQueue、LifoQueueおよびPriorityQueu、multiprocessing.Queue、heapqは可変シーケンスをスタックキューまたは優先キューとして使用することができる)
  • を使用する.
    Pythonフォーマット出力
    フォーマット出力を行う場合、%rと%sの違いはrepr()関数処理オブジェクトとstr()関数処理オブジェクトの違いのようなものである.
  • %s->str()で、スマートです.
  • %r->repr()は、処理が簡単で直接的である.単純なオブジェクトを扱う場合、両者にはほとんど差がない.

  • 本文は重点的にいくつかの両者の差別化の用法を列挙する:
  • 文字列の処理時
  • >> s = 'world'
    
    >> print('hello %s'%s)
    hello world
    >> print('hello %r'%s)
    hello 'world'
    
    >> str(s)
    'world'
    >> repr(s)
    "'world'"
    2. datetime     datetime   
    >> from datetime import datetime 
    >> timeinfo = datetime.today()
    
    >> timeinfo
    datetime.datetime(2016, 6, 7, 21, 17, 34, 925488)
    >> type(timeinfo)
    datetime.datetime
    
    >> repr(timeinfo)
    'datetime.datetime(2016, 6, 7, 21, 17, 34, 925488)'
    >> str(timeinfo)
    '2016-06-07 21:17:34.925488'

    逆アセンブリ関数python opcode
    Python disモジュールは、Pythonコードの逆アセンブリをサポートし、バイトコード命令を生成します.
    In[1]: def test():
    ...         x = 1
    ...         if x < 3:
    ...             return "yes"
    ...         else:
    ...             return "no"
    
    In[2]: dis.dis(test)
      2           0 LOAD_CONST               1 (1)
                  3 STORE_FAST               0 (x)
     
      3           6 LOAD_FAST                0 (x)
                  9 LOAD_CONST               2 (3)
                 12 COMPARE_OP               0 (>   22 LOAD_CONST               4 ('no')
                 25 RETURN_VALUE        
                 26 LOAD_CONST               0 (None)
                 29 RETURN_VALUE        
    
    >>> def add(a, b = 0):
    ...     return a + b
    ... 
    >>> 
    
    >>> dis.dis(add)
      2           0 LOAD_FAST                0 (a)
                  2 LOAD_FAST                1 (b)
                  4 BINARY_ADD
                  6 RETURN_VALUE
    >>>
    
    

    class memoryview(obj)はpythonの内蔵クラスであり、memoryviewでobjectを参照する場合はbuffer protocolをサポートする必要があり、python 3でbuffer protocolをサポートするobjにはbytesとbytearrayがあり、memoryviewは異なる方法で同じメモリを読み取り、操作することができ、元のメモリバイトは勝手に移動しない.Cの強い回転と同様に、メモリコピーがないというメリットがあります.
    たとえば、memoryviewを使用して、シンボル整数配列の短い整数配列のデータを変更します.
    from array import array
    from random import random
    
    numbers = array('h', [-2, -1, 0, 1, 2]) #signed short
    memv = memoryview(numbers)      #5                memoryview
    print (len(memv))               #    
    print (memv.tolist())           #       
    
    memv_oct = memv.cast('B')       #               
    print (memv_oct.tolist())
    
    memv_oct[5] = 4                 #   5      4
    print (numbers)                 #       2                4,                1024
    
        :
    
    5                       #    
    [-2, -1, 0, 1, 2]       #      
    [254, 255, 255, 255, 0, 0, 1, 0, 2, 0]#                 
    array('h', [-2, -1, 1024, 1, 2])   #        
    

    bytearrayはPython 2のstrに対して可変(mutable)のバイトシーケンスであるがstrは可変(immutable)である.Python 3ではstrはデフォルトでunicode符号化されているためbytearrayでのみバイトでアクセスできます.次の2つの動作の比較:簡単な点は、strとbytearrayのスライス操作が新しいスライスstrとbytearryを生成し、データをコピーし、memoryviewを使用してからはしません.
    python 2の例
    memoryviewを使用しない
    >> a = 'aaaaaa'
    >> b = a[:2]    #         
    
    >> a = bytearray('aaaaaa')
    >> b = a[:2]    #      bytearray
    >> b[:2] = 'bb' #  b      a
    >> a
    bytearray(b'aaaaaa')
    >> b
    bytearray(b'bb')

    memoryviewの使用
    >> a = 'aaaaaa'
    >> ma = memoryview(a)
    >> ma.readonly  #    memoryview
    True
    >> mb = ma[:2]  #          
    
    >> a = bytearray('aaaaaa')
    >> ma = memoryview(a)
    >> ma.readonly  #    memoryview
    False
    >> mb = ma[:2]      #        bytearray
    >> mb[:2] = 'bb'    #  mb      ma   
    >> mb.tobytes()
    'bb'
    >> ma.tobytes()
    'bbaaaa'

    Pythonには様々な呼び出し可能なタイプがあるので、設定したcallable()関数を判断します.
    >>> abs, str, 13
    (, , 13)
    >>> [callable(obj) for obj in (abs, str, 13)]
    [True, True, False]

    random.shuffleシーケンスの乱れ
    >>> import random
    >>> a=range(10)
    >>> random.shuffle(a)
    >>> a
    [1, 0, 8, 5, 6, 7, 9, 3, 2, 4]
    >>> random.shuffle(a)
    >>> a
    [7, 5, 6, 2, 1, 8, 9, 0, 3, 4]

    vim常用ショートカット
  • 0→数字ゼロ、行頭
  • $→本行行末
  • a→カーソル後に
  • を挿入
  • o→現在の行の後に新しい行を挿入する
  • O→現在の行の前に新しい行を挿入する
  • cw→カーソル位置から単語の末尾までの文字
  • を置き換える.
  • . →(小数点)前回のコマンド
  • を繰り返すことができる.
  • NG→N行目(注意コマンドのGは大文字ですが、私は一般的にN行目、例えば:137行目)
  • を使用します.
  • gg→1行目まで.(1 G相当、または:1)
  • G→最後の行へ.
  • Insertモードでは、単語の先頭を入力して、またはを押すと、自動補完機能が表示されます...
  • 組み込み関数
    Math
    Function    Description
    abs()    Returns absolute value of a number
    divmod()    Returns quotient and remainder of integer division
    max()    Returns the largest of the given arguments or items in an iterable
    min()    Returns the smallest of the given arguments or items in an iterable
    pow()    Raises a number to a power
    round()    Rounds a floating-point value
    sum()    Sums the items of an iterable
    
    Type Conversion
    Function    Description
    ascii()    Returns a string containing a printable representation of an object
    bin()    Converts an integer to a binary string
    bool()    Converts an argument to a Boolean value
    chr()    Returns string representation of character given by integer argument
    complex()    Returns a complex number constructed from arguments
    float()    Returns a floating-point object constructed from a number or string
    hex()    Converts an integer to a hexadecimal string
    int()    Returns an integer object constructed from a number or string
    oct()    Converts an integer to an octal string
    ord()    Returns integer representation of a character
    repr()    Returns a string containing a printable representation of an object
    str()    Returns a string version of an object
    type()    Returns the type of an object or creates a new type object
    
    Iterables and Iterators
    Function    Description
    all()    Returns True if all elements of an iterable are true
    any()    Returns True if any elements of an iterable are true
    enumerate()    Returns a list of tuples containing indices and values from an iterable
    filter()    Filters elements from an iterable
    iter()    Returns an iterator object
    len()    Returns the length of an object
    map()    Applies a function to every item of an iterable
    next()    Retrieves the next item from an iterator
    range()    Generates a range of integer values
    reversed()    Returns a reverse iterator
    slice()    Returns a slice object
    sorted()    Returns a sorted list from an iterable
    zip()    Creates an iterator that aggregates elements from iterables
    
    Composite Data Type
    Function    Description
    bytearray()    Creates and returns an object of the bytearray class
    bytes()    Creates and returns a bytes object (similar to bytearray, but immutable)
    dict()    Creates a dict object
    frozenset()    Creates a frozenset object
    list()    Constructs a list object
    object()    Returns a new featureless object
    set()    Creates a set object
    tuple()    Creates a tuple object
    
    Classes, Attributes, and Inheritance
    Function    Description
    classmethod()    Returns a class method for a function
    delattr()    Deletes an attribute from an object
    getattr()    Returns the value of a named attribute of an object
    hasattr()    Returns True if an object has a given attribute
    isinstance()    Determines whether an object is an instance of a given class
    issubclass()    Determines whether a class is a subclass of a given class
    property()    Returns a property value of a class
    setattr()    Sets the value of a named attribute of an object
    super()    Returns a proxy object that delegates method calls to a parent or sibling class
    
    Input/Output
    Function    Description
    format()    Converts a value to a formatted representation
    input()    Reads input from the console
    open()    Opens a file and returns a file object
    print()    Prints to a text stream or the console
    
    Variables, References, and Scope
    Function    Description
    dir()    Returns a list of names in current local scope or a list of object attributes
    globals()    Returns a dictionary representing the current global symbol table
    id()    Returns the identity of an object
    locals()    Updates and returns a dictionary representing current local symbol table
    vars()    Returns __dict__ attribute for a module, class, or object
    
    Miscellaneous
    Function    Description
    callable()    Returns True if object appears callable
    compile()    Compiles source into a code or AST object
    eval()    Evaluates a Python expression
    exec()    Implements dynamic execution of Python code
    hash()    Returns the hash value of an object
    help()    Invokes the built-in help system
    memoryview()    Returns a memory view object
    staticmethod()    Returns a static method for a function
    __import__()    Invoked by the import statement
    
    

    演算子に関係のない特殊な方法
          
        /          __repr__、__str__、__format__、__bytes__
         __abs__、__bool__、__complex__、__int__、__float__、__hash__、__index__
         __len__、__getitem__、__setitem__、__delitem__、__contains__
         __iter__、__reversed__、__next__
          __call__
          __enter__、__exit__
            __new__、__init__、__del__
         __getattr__、__getattribute__、__setattr__、__delattr__、__dir__
          __get__、__set__、__delete__
            __prepare__、__instancecheck__、__subclasscheck__
    

    Bisectモジュールは秩序あるシーケンスを管理する
    bisect.bisect_left(a,x, lo=0, hi=len(a)) :
            a     x  index。lo   hi          ,         。   x     ,      。     index。
    bisect.bisect_right(a,x, lo=0, hi=len(a))
    bisect.bisect(a, x,lo=0, hi=len(a)) :
     2     bisect_left   ,    x     ,      。
    bisect.insort_left(a,x, lo=0, hi=len(a)) :
          a     x。  a.insert(bisect.bisect_left(a,x, lo, hi), x)      。
    bisect.insort_right(a,x, lo=0, hi=len(a))
    bisect.insort(a, x,lo=0, hi=len(a)) :
      insort_left   ,    x     ,      。
    Bisect             : bisect*       index,         ;  insort*        。
    

    listが最適選択でない場合、dictはpythonのコアタイプですが、空間的に時間を変えた結果、メモリを比較し、tupleはdict構造の比較的良い代替であり、setは含めるかどうかと重み付けするのに適しています.
    from array import array  
    from random import random
    floats = array('d', (random() for i in range(10**7)))  
    fp = open('floats.bin', 'wb')
    floats.tofile(fp)  
    fp.close()
    floats2 = array('d')  
    fp = open('floats.bin', 'rb')
    floats2.fromfile(fp, 10**7)  
    fp.close()
    floats2 == floats
    

    Python_4つのキューを内蔵
    from queue import Queue #LILO  
    q = Queue() #      
    q.put(0)    #         
    q.put(1)
    q.put(2)
    print('LILO  ',q.queue)  #          
    print(q.get())  #           
    print(q.queue)
    
    from queue import LifoQueue #LIFO  
    lifoQueue = LifoQueue()
    lifoQueue.put(1)
    lifoQueue.put(2)
    lifoQueue.put(3)
    print('LIFO  ',lifoQueue.queue)
    lifoQueue.get() #           
    lifoQueue.get()
    print(lifoQueue.queue)
    
    from queue import PriorityQueue #    
    priorityQueue = PriorityQueue() #        
    priorityQueue.put(3)    #    
    priorityQueue.put(78)   #    
    priorityQueue.put(100)  #    
    print(priorityQueue.queue)  #             
    priorityQueue.put(1)    #    
    priorityQueue.put(2)    #    
    print('     :',priorityQueue.queue)  #             
    priorityQueue.get() #             
    print('       ',priorityQueue.queue)
    priorityQueue.get() #             
    print('       ',priorityQueue.queue)  #       
    priorityQueue.get() #             
    print('       ',priorityQueue.queue)  #       
    priorityQueue.get() #             
    print('       ',priorityQueue.queue)  #       
    priorityQueue.get() #             
    print('      :',priorityQueue.queue)  #             
    
    from collections import deque   #    
    dequeQueue = deque(['Eric','John','Smith'])
    print(dequeQueue)
    dequeQueue.append('Tom')    #        
    dequeQueue.appendleft('Terry')  #        
    print(dequeQueue)
    dequeQueue.rotate(2)    #    2 
    print('    2     ',dequeQueue)
    dequeQueue.popleft()    #            
    print('           :',dequeQueue)
    dequeQueue.pop()    #            
    print('           :',dequeQueue)
    
    
                       ,             。     ,      :
    from multiprocessing import Process, Queue
    myqueue = Queue(100)
    
    
    ##   
    
    https://blog.csdn.net/sinat_38682860/article/details/80392493 
    https://www.cnblogs.com/cmnz/p/6936181.html
    

    キーワード
    from keyword import kwlist
    print(kwlist)
    

    builtinsモジュール
    import builtins
    dir(builtins)
    
    
    

    Python locals()の罠
    https://segmentfault.com/a/1190000012724861
    
    def test():
        globals()['a2'] = 4
    test()
    print a2   #    4
    
    
    def aaaa():
        print locals()
        for i in ['a', 'b', 'c']:
            locals()[i] = 1
        print locals()
        print a #   :NameError: global name 'a' is not defined
    aaaa()

    動的に変数割り当てを行うと、locals()が見たのは、確かに関数のローカルネーミング空間の内容ですが、それ自体がローカルネーミング空間を代表することはできません.これはエージェントのようなもので、A、B、Cのものを集めて見せてくれましたが、私はこのエージェントを簡単に変えることで、A、B、Cが本当に持っているものを変えることはできません.したがって、print aはlocals()[i]=1で動的に値を割り当てるとNameError異常をトリガーしますが、globals()は確かに本当のグローバルネーミングスペースなので、locals()は読み取り専用、globals()は読み取り可能、書き込み可能と言われます.
    x += y vs x = x + y
    一般的な可変タイプの変数ではこの2つの方法に違いはありませんが、list(リスト)のような可変タイプではdict(辞書)に違いがあり、x+=yはlistの値をその場で変更し、x=x+yは新しいlistを作成し、xを再バインドし、id(x)で見ることができます.
    l = l + [3, 4, 5]          BINARY_ADD
    l += [3, 4, 5]           INPLACE_ADD
    

    +=実際には、+よりも1つの書き込み自体の機能が多いため、強化版と言えるはずです.でも、自分に書けるかどうかは、相手自身が支持しているかどうか、つまりPy_が備わっているかどうかにかかっています.NotImplemented ID、sq_をサポートするかどうかinplace_concatは、備えていれば実現できるが、そうでなければ+効果と同じである.
    これだけでなく、可変タイプと可変タイプを混合して使用すると、より驚くべき発見があります.
    >>> t = ([],)
    >>> t[0] += [2, 3]
    Traceback (most recent call last):
      File "", line 1, in ?
    TypeError: object doesn't support item assignment
    >>> t
    ([2, 3],)

    明らかに、メタグループは要素の付与をサポートしていません.しかし、彼に+=を使用すると、メタグループのlistは確かに変わりました.原因は依然として+=listの値をその場で変更することである.しかし,メタグループの付与は許されず,異が発生するとメタグループ中のlistはその場で変更される.これは私個人が非常に致命的だと思っている罠です.解決策:+=を使用しないか、整数のみで使用します.
    ()を使用してtupleを作成する
    >>> a=(1) #     
    >>> type(a)
    
    
    >>> a=(1,) #     
    >>> type(a)
    

    Pythonのlistループでデータを削除する正しい方法
    一般的なソリューション:
    num_list = [1, 2, 3, 4, 5, 2, 2, 4]
    
    1.       
    
    for i in range(len(num_list) - 1, -1, -1):  #   
        if num_list[i] == 2:
            num_list.pop(i)
    print(num_list)
    
    2.      list,     list。     list,         ,             。
    
    for item in num_list[:]:    #      num_list      
        if item == 2:
            num_list.remove(item) #           item
    print(num_list)
    
    
    3.          ,        (  determine(x)        ):
    
    list = [x for x in list if not determine(x)]
    
    4.          ,        
    
    list[:] = [x for x in list if not determine(x)]
    
    5. python2.x ifilterfalse()  
    
    from itertools import ifilterfalse()
    list[:] = ifilterfalse(determine, list)
    
    6. Python3 filterfalse()  
    
    from itertools import filterfalse
    list[:] = filterfalse(determine, list)
    
      5,6                    。

    役割ドメイン解析はLEGBルールに基づいており,それぞれLocal,Enclosing,Global,Built-inである.
    関数内で定義されたローカル変数はグローバル変数を使用するにはglobalで宣言する必要があります.
    def local_var_err():
        b += [3]  # UnboundLocalError: local variable 'b' referenced before assignment
        b = b + [2]  # UnboundLocalError: local variable 'b' referenced before assignment
    
    

    反復器とジェネレータのパフォーマンスの比較
    In [109]: %timeit -n100 a = (i for i in range(100000))
    100 loops, best of 3: 659 µs per loop
    
    In [110]: %timeit -n100 b = [i for i in range(100000)]
    100 loops, best of 3: 2.68 ms per loop
    

    反復器とジェネレータのパフォーマンスの比較
    In [112]: %timeit -n100 for x in (i for i in range(100000)):pass
    100 loops, best of 3: 4.23 ms per loop
    
    In [113]: %timeit -n100 for x in [i for i in range(100000)]:pass
    100 loops, best of 3: 3.49 ms per loop
    

    くうかんへんかんじかん
    ローカル変数の使用
    # -*- coding:utf-8 -*-
    import timeit
    
    test_dict = {}
    
    class dome(object):
        def test_class(self):
            num = 100
            self.test_dict = {}        #     ,             {}
            for i in range(num):
                self.test_dict[i] = i
    
        def test_local(self):
            num = 100
            test_dict = {}             #     ,             {}
            for i in range(num):
                test_dict[i] = i
            self.test_dict = test_dict
    
        def test_global(self):
            num = 100
            global test_dict
            test_dict = {}              #     ,             {}
            for i in range(num):
                test_dict[i] = i
    
    s = dome()
    
    print(timeit.timeit(stmt=s.test_class))    # 9.75976037823
    print(timeit.timeit(stmt=s.test_local))    # 7.17526431985
    print(timeit.timeit(stmt=s.test_global))   # 7.57540534177
    
    """
    1.             
    2.                
              /         ,                   ,              。                。
    """

    文字列リストをつなぐときにjoinを使用する
    a=list(str(range(1000)))
    
    In [126]: %%timeit
    s=""
    for x in a:
        s+=x
       .....: 
    1000 loops, best of 3: 304 µs per loop
    
    In [127]: %%timeit
       .....: s="".join(a)
       .....: 
    10000 loops, best of 3: 59.3 µs per loop
    
         https://blog.csdn.net/xdhstc/article/details/51719892

    if is True比較if==True,リスト導出.
    # -*- coding:utf-8 -*-
    import timeit
    
    def test_1():
        a = [True] * 100
        s = []
        for i in a:
            if i == True:
                s.append(i)
        return s
    
    
    def test_2():
        a = [True] * 100
        return [i for i in a if i is True]
    
    
    def test_3():
        a = [True] * 100
        return [i for i in a if i == True]
    
    
    def test_4():
        a = [True] * 100
        return [i for i in a if i]
    
    
    print(timeit.timeit(stmt=test_1))  # 11.5888194259
    print(timeit.timeit(stmt=test_2))  # 6.00562291202
    print(timeit.timeit(stmt=test_3))  # 7.15504198257
    print(timeit.timeit(stmt=test_4))  # 4.29275713242

    powではなく**を使う
    In [145]: %timeit -n100000 c = pow(2,20)
    100000 loops, best of 3: 89.3 ns per loop
    
    In [146]: %timeit -n100000 c = 2**20
    100000 loops, best of 3: 22.2 ns per loop
    
    

    条件判断付きネストforサイクルの場合はできるだけ条件を分析してサイクル回数を減らす
    # -*- coding:utf-8 -*-
    import timeit
    
    
    def test1():
        s = []
        for z in range(10):
            for y in range(100):
                for x in range(1000):
                    if x > 100 and y > 50 and z > 5:
                        return s
                    s.append((x, y, z))
    
    
    
    def test2():
        s = []
        for x in range(1000):
            for y in range(100):
                for z in range(10):
                    if x > 100 and y > 50 and z > 5:
                        return s
                    s.append((x, y, z))
    
    
    
    print(timeit.timeit(stmt=test1, number=100))    # 14.1777687741
    print(timeit.timeit(stmt=test2, number=100))    # 2.03417086749
    print(sorted(test1()) == sorted(test2()))       # False
    print(len(test1()))                             # 651101
    print(len(test2()))                             # 101516