2016-02-22 7 views
11

2つのリストがすべてのインデックスに対して同じタイプの項目を持っているかどうかをチェックしたいと思います。私は2つのリストがPythonのタイプで等しいかどうか確認してください

y = [3, "a"] 
x = [5, "b"] 
z = ["b", 5] 

を持っている場合たとえば、チェックがxyためTrueでなければなりません。 同じ位置にある要素の型が等しくないため、yzのチェックはFalseである必要があります。

答えて

18

それぞれtypeにジャストmap要素とそれらの比較:Pythonの3のために

>>> x = [5, "b"] 
>>> y = [3, "a"] 
>>> z = ["b", 5] 
>>> map(type, x) == map(type, y) 
True 
>>> map(type, x) == map(type, z) 
False 

を、あなたもlist機能を使用するか、またはlist comprehensionのいずれかで、適切なリストにmap発電機を有効にする必要があります:

>>> list(map(type, x)) == list(map(type, y)) 
True 
>>> [type(i) for i in x] == [type(i) for i in z] 
False 

私は上記のゾルを比較すると、いくつかのタイミング解析を行いました@timgebの値に、allizipを使用し、異なる位置に最初の一致しないタイプを入力します。予想どおり、mapの解決に要した時間は、入力ごとにほぼ正確に同じですが、all + izipの解は、最初の差の位置によっては非常に速いか、3倍の時間がかかります。

In [52]: x = [1] * 1000 + ["s"] * 1000 
In [53]: y = [2] * 1000 + ["t"] * 1000 # same types as x 
In [54]: z = ["u"] * 1000 + [3] * 1000 # difference at first element 
In [55]: u = [4] * 2000    # difference after first half 
In [56]: %timeit map(type, x) == map(type, y) 
10000 loops, best of 3: 129 µs per loop 
In [58]: %timeit all(type(i) == type(j) for i, j in izip(x, y)) 
1000 loops, best of 3: 342 µs per loop 
In [59]: %timeit all(type(i) == type(j) for i, j in izip(x, z)) 
1000000 loops, best of 3: 748 ns per loop 
In [60]: %timeit all(type(i) == type(j) for i, j in izip(x, u)) 
10000 loops, best of 3: 174 µs per loop 
+1

"all(...)"を使うと、@timgebのようなものが速くなります。 – fransua

+0

@fransuaおそらく、itertools.izip_longest'を使う必要があります。等しくない長さであり、IMHOでは(リストが特に長い場合を除いて)コードを複雑にするだけです。 –

18

allと遅延評価:Pythonの3の

>>> from itertools import izip 
>>> all(type(a) == type(b) for a,b in izip(x,y)) 
True 

使用定期zip、それはすでに発電を返します。

リストの長さが異なる場合は、先頭の長さを確認してください。長さをチェックすると、非常に高速なO(1)操作:

>>> len(x) == len(y) and all(type(a) == type(b) for a,b in izip(x,y)) 
True 
>>> x = [5,"b",'foo'] 
>>> len(x) == len(y) and all(type(a) == type(b) for a,b in izip(x,y)) 
False 

andは、長さが異なる場合allも呼び出されないことを意味し、短絡が評価されます。あなたはジェネレータ式を使用する場合

+2

いいですが、長さの違うリストではうまくいきません...代わりに 'itertools.izip_longest'を使用するのでしょうか? –

+0

Python 2で 'zip'を使用できないのはなぜですか? – zondo

+0

@ zondoできるだけジェネレータの代わりにタプルのリストを生成します。 – timgeb

2

それは非常に簡単です:この例では

are_equal = all(type(i) == type(j) for i, j in zip(x, y)) 

を、xyは、あなたがチェックしているリストです。あなたがに追加することができます何かしたい場合:そのようにして

lists = (x, y) 
are_equal = all(len(set(type(j) for j in i)) == 1 for i in zip(*lists)) 

を、あなただけのlistsを変更することができ、そしてそれはまだ動作します。 setがすべての重複を削除するという事実を利用して動作します。 zip()が返す各タプルに対して、各アイテムのタイプのセットを作成し、セットの長さが1であるかどうかを調べて、それらが同じかどうかをチェックします。ラムダと

+0

2番目の部分は、位置に基づいて型を比較しません。特に、 'x'と' z'に 'true'を表示します。 –

+0

@tobias_k:おっと。私はちょうどカップルの文字を残しました。今修正されました。 – zondo

+0

あなたは何を意味するのか分かりません。 'set(iのjの型(j)))'は、現在のzipタプルの各要素の型の集合を返します。その集合の長さが1でない場合、それらの要素の1つは、他の要素とは異なる型です。私はそれをテストし、すべての外観に、それは動作します。私は行方不明のものがありますか? – zondo

3

別のオプション:

>>> x = [5, "b"] 
>>> y = [3, "a"] 
>>> z = ["b", 5] 
>>> g = lambda t: [type(i) for i in t] 
>>> g(x) == g(y) 
True 
>>> g(x) == g(z) 
False 
0
def equalTypes(list1, list2): 
    if len(list1) != len(list2): 
     return False 
    for index, item in enumerate(list1): 
     if type(item) != type(list2[index]): 
      return False 
    return True 

は、私はいくつかの種類が、私はFalseを返す不一致ときにと(彼らは同じ第1の長さを持っているかどうかをチェック)リストを反復。最後(不一致なし)に私は真を返します。

+0

コードを説明してください... –

0

あなたは、全体のリストのコピーを保存することなく、あなたにまともな平均時間を与えるitertoolsoperator.eqを使用して、遅延評価を維持することができます:

In [12]: from itertools import imap, starmap, izip 

In [13]: %timeit map(type, x) == map(type, y) 
10000 loops, best of 3: 182 µs per loop 

In [14]: %timeit all(type(i) == type(j) for i, j in izip(x, u)) 
1000 loops, best of 3: 239 µs per loop 

In [15]: timeit all(type(i) == type(j) for i, j in izip(x, z)) 
1000000 loops, best of 3: 1.02 µs per loop 

In [16]: %timeit all(type(i) == type(j) for i, j in izip(x, u)) 
1000 loops, best of 3: 234 µs per loop 

In [17]: timeit all(starmap(eq, izip(imap(type, x), imap(type, y)))) 
1000 loops, best of 3: 238 µs per loop 

In [18]: timeit all(starmap(eq, izip(imap(type, x), imap(type, u)))) 
10000 loops, best of 3: 120 µs per loop 

In [19]: timeit all(starmap(eq, izip(imap(type, x), imap(type, z)))) 
1000000 loops, best of 3: 901 ns per loop 

リストは異なる長さであれば、単に最初の長さをチェックすることもウルド最も簡単かつ最速のが、あなたがロジックに組み込むした場合、あなたはitertools.izip_longestからfillvalueとしてオブジェクトを使用することができます。

all(starmap(eq, izip_longest(imap(type, x), imap(type, y), fillvalue=object())) 
関連する問題