ホームページ  >  記事  >  バックエンド開発  >  Python セット型の詳細な図解説明 (リスト タプル dict セット ジェネレーター)

Python セット型の詳細な図解説明 (リスト タプル dict セット ジェネレーター)

高洛峰
高洛峰オリジナル
2017-03-20 10:24:001933ブラウズ

Python組み込みコレクション型には、list、tuple、set、dict が含まれます。

List: 配列のように見えますが、配列よりも強力で、インデックス付け、スライス、検索、加算などの機能をサポートしています。

タプル: 関数はリストに似ていますが、生成されると長さと要素は可変ではなく (要素の要素は依然として可変です)、より軽量で安全なリストであると思われます。

辞書 dict: key と同じプロパティを持つキーと値のペア構造のハッシュ テーブル。順序付けがなく、繰り返しがなく、追加、削除、変更が便利で高速です。

set: 順序付けされておらず、繰り返しのないセットは、キーだけを持ち、値を持たない辞書です。結局のところ、Python では値が必要ないため、大幅に節約されます。ポインタの。

ジェネレーター:

ジェネレーター またはリスト内包表記と呼ばれ、実際にはデータ構造ではなく、アルゴリズムと一時的な 状態のみを含みます。反復の機能を持っています。 まずメモリ使用量を確認し、ジェネレーターを使用してセット、辞書、ジェネレーター、タプル、および 100,000 要素のリストを生成します。 dict、set、list、tuple が消費するメモリは順に減少し、生成されるオブジェクトのサイズも変わりません。ジェネレーターはデータテーブルを生成しないため、メモリを消費する必要はありません:

import sys
from memory_profiler import profile

@profile
def create_data(data_size):
    data_generator = (x for x in xrange(data_size))
    data_set = {x for x in xrange(data_size)}
    data_dict = {x:None for x in xrange(data_size)}
    data_tuple = tuple(x for x in xrange(data_size))
    data_list = [x for x in xrange(data_size)]
    return data_set, data_dict, data_generator, data_tuple, data_list

data_size = 100000
for data in create_data(data_size):
    print data.__class__, sys.getsizeof(data)

Line #    Mem usage    Increment   Line Contents
================================================
    14.6 MiB      0.0 MiB   @profile
                            def create_data(data_size):
    14.7 MiB      0.0 MiB       data_generator = (x for x in xrange(data_size))
    21.4 MiB      6.7 MiB       data_set = {x for x in xrange(data_size)}
    29.8 MiB      8.5 MiB       data_dict = {x:None for x in xrange(data_size)}
    33.4 MiB      3.6 MiB       data_tuple = tuple(x for x in xrange(data_size))
    38.2 MiB      4.8 MiB       data_list = [x for x in xrange(data_size)]
    38.2 MiB      0.0 MiB       return data_set, data_dict, data_generator, data_tuple, data_list
 
<type &#39;set&#39;> 4194528
<type &#39;dict&#39;> 6291728
<type &#39;generator&#39;> 72
<type &#39;tuple&#39;> 800048
<type &#39;list&#39;> 824464

もう一度検索パフォーマンスを見てみましょう。 dict と set は一定の検索時間 (O(1)) であり、list と tuple は線形検索です。 (O(n)) 回、ジェネレーターを使用して指定されたサイズの要素のオブジェクトを生成し、ランダムに生成された数値を使用して以下を見つけます。ただし、これらの乱数はすべてコレクション内で見つけることができます。生成された数値の半分が見つかり、半分が見つからないように乱数の方法を変更します。印刷された情報から、最悪の検索例が半分になると、リストとタプルのパフォーマンスがさらに低下することがわかります。

import time
import sys
import random
from memory_profiler import profile

def create_data(data_size):
    data_set = {x for x in xrange(data_size)}
    data_dict = {x:None for x in xrange(data_size)}
    data_tuple = tuple(x for x in xrange(data_size))
    data_list = [x for x in xrange(data_size)]
    return data_set, data_dict, data_tuple, data_list

def cost_time(func):
    def cost(*args, **kwargs):
        start = time.time()
        r = func(*args, **kwargs)
        cost = time.time() - start
        print &#39;find in %s cost time %s&#39; % (r, cost)
        return r, cost  #返回数据的类型和方法执行消耗的时间
    return cost

@cost_time
def test_find(test_data, data):
    for d in test_data:
        if d in data:
            pass
    return data.__class__.__name__

data_size = 100
test_size = 10000000
test_data = [random.randint(0, data_size) for x in xrange(test_size)]
#print test_data
for data in create_data(data_size):
    test_find(test_data, data)

输出:
----------------------------------------------
find in <type &#39;set&#39;> cost time 0.47200012207
find in <type &#39;dict&#39;> cost time 0.429999828339
find in <type &#39;tuple&#39;> cost time 5.36500000954
find in <type &#39;list&#39;> cost time 5.53399991989

要素数は 10 から 500 に増加します。毎回 100,000 回の検索に必要な時間を計算すると、結果は次のようになります。 dict と set には要素があり、検索時間は常に一定です。 dict と tuple は、要素が増加するにつれて直線的な増加時間を示します。

def randint(index, data_size):
    return random.randint(0, data_size) if (x % 2) == 0 else random.randint(data_size, data_size * 2)

test_data = [randint(x, data_size) for x in xrange(test_size)]

输出:
----------------------------------------------
find in <type &#39;set&#39;> cost time 0.450000047684
find in <type &#39;dict&#39;> cost time 0.397000074387
find in <type &#39;tuple&#39;> cost time 7.83299994469
find in <type &#39;list&#39;> cost time 8.27800011635

反復時間の差は非常にわずかで、dict と set の方がわずかに時間がかかります。 :

import matplotlib.pyplot as plot
from numpy import *

data_size = array([x for x in xrange(10, 500, 10)])
test_size = 100000
cost_result = {}
for size in data_size:
    test_data = [randint(x, size) for x in xrange(test_size)]
    for data in create_data(size):
        name, cost = test_find(test_data, data) #装饰器函数返回函数的执行时间
        cost_result.setdefault(name, []).append(cost)

plot.figure(figsize=(10, 6))
xline = data_size
for data_type, result in cost_result.items():
    yline = array(result)
    plot.plot(xline, yline, label=data_type)

plot.ylabel(&#39;Time spend&#39;)
plot.xlabel(&#39;Find times&#39;)

plot.grid()

plot.legend()
plot.show()

Python集合类型(list tuple dict set generator)图文详解

要素の削除にかかる時間のイメージ 以下のように、1000 個の要素をランダムに削除します。タプル型では要素を削除できないため、比較は行われません。

Python集合类型(list tuple dict set generator)图文详解

要素の半分をランダムに削除します。グラフは指数関数的な時間 (O(n2)) で増加します。

Python集合类型(list tuple dict set generator)图文详解

要素の追加にかかる時間の統計は、10000 単位で増加し、すべて線形成長時間です。違いはありません。タプル型では新しい要素を追加できないため、比較は行われません。

以上がPython セット型の詳細な図解説明 (リスト タプル dict セット ジェネレーター)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。