2

Pythonの辞書のリストがあります。リストの各要素にはtype、要素のタイプのキーがあります。このようなもの:

e1 = {"type": 1, "value": 23.1}
e2 = {"type": 1, "value": 21.1}
e3 = {"type": 2, "value": -10.1}
e4 = {"type": 1, "value": -2.59}
l = [e1, e2, e3, e4]

lリスト内のすべての要素が同じであるかどうかを知りたいのですがtype

私はこれを持っています:

def same_type(l):
    return l[0].type == l[1].type == l[2].type == l[3].type

リストが常に同じサイズになると仮定すると、これを行うためのよりPython的な方法はありますか?

4

3 に答える 3

8

私の頭に浮かぶ最初のこと:

all(e['type'] == L[0]['type'] for e in L)

タイプのセットの長さ:

len(set(e['type'] for e in L)) == 1

ジェネレータよりも効率的ですがall、リストでは効率的ではありません。

>>> %timeit all(e['type'] == l[0]['type'] for e in l)
1000000 loops, best of 3: 784 ns per loop

>>> %timeit len(set(e['type'] for e in l)) == 1
1000000 loops, best of 3: 676 ns per loop

>>> %timeit all([e['type'] == l[0]['type'] for e in l])
1000000 loops, best of 3: 602 ns per loop

キャッシュ付きl[0]['type']

>>> t1 = l[0]['type']
>>> %timeit all([e['type'] == t1 for e in l])
1000000 loops, best of 3: 447 ns per loop

>>> %timeit all(e['type'] == t1 for e in l)
1000000 loops, best of 3: 655 ns per loop

setlist-compを使用すると、genexprを使用した場合よりもさらに遅くなります。

>>> %timeit len(set([gettype(e) for e in l])) == 1
1000000 loops, best of 3: 735 ns per loop

 

set短絡する可能性がない場合よりも速い別の方法を考えました。

>>> %timeit [e['type'] for e in l].count(t1) == len(l)
1000000 loops, best of 3: 421 ns per loop

 

別の編集:明らかに最も簡単な方法が最速です:

In [31]: def same_type(L):
   ....:     t1 = L[0]['type']
   ....:     for e in L:
   ....:         if e['type'] != t1:
   ....:             return False
   ....:     return True
   ....:

In [32]: %timeit same_type(l)
1000000 loops, best of 3: 352 ns per loop

同じタイプの長い入力(短絡なし)

In [47]: l = [{'type': 1} for _ in range(1000)]

In [48]: %timeit same_type(l)
10000 loops, best of 3: 37.6 us per loop

In [49]: %timeit  all(e['type'] == l[0]['type'] for e in l)
10000 loops, best of 3: 112 us per loop

In [50]: %timeit all([e['type'] == l[0]['type'] for e in l])
10000 loops, best of 3: 103 us per loop

In [51]: %timeit len(set(e['type'] for e in l)) == 1
10000 loops, best of 3: 63.3 us per loop

異なるタイプの長い入力(すぐに短絡)

In [40]: l = [{'type': x} for x in range(1000)]

In [43]: %timeit same_type(l)
1000000 loops, best of 3: 337 ns per loop

In [44]: %timeit  all(e['type'] == l[0]['type'] for e in l)
1000000 loops, best of 3: 656 ns per loop

In [45]: %timeit all([e['type'] == l[0]['type'] for e in l])
10000 loops, best of 3: 99.4 us per loop

In [46]: %timeit len(set(e['type'] for e in l)) == 1
10000 loops, best of 3: 68.6 us per loop
于 2013-02-25T18:06:20.030 に答える
5

aを使用しset()てすべてのタイプを収集し、長さが1であるかどうかをテストします。

def same_type(L):
    if not L: return True  # empty list case
    return len(set(d['type'] for d in L)) == 1

これはすべての要素をスキャンする必要があります。最初の要素と比較することもできます。その時点で、一致しない要素を見つけるのに十分なテストを行うだけで済みます。

def same_type(L):
    if not L: return True  # empty list case
    t = L[0]['type']
    return all(t == d['type'] for d in L)

小さい入力の場合、set()アプローチは高速ですが、大きいset()入力の場合、入力に2番目のタイプが存在する可能性が十分に大きい場合、2番目の形式はアプローチを打ち負かすことができます。

于 2013-02-25T18:07:01.657 に答える
4

の任意の長さで動作しlstます:

def same_type(lst):
    return all(d['type'] == lst[0]['type'] for d in lst[1:])

異なるものが見つかるlen(set(...)) == 1とすぐに停止するため、比較すると高速です。type

于 2013-02-25T18:06:25.550 に答える