リスト内のすべての要素が等しいかどうかをチェックする 質問する

リスト内のすべての要素が等しいかどうかをチェックする 質問する

を受け取り、入力リスト内のすべての要素が標準の等価演算子を使用して互いに等しいと評価された場合に出力し、そうでない場合はlist出力する関数が必要です。TrueFalse

リストを反復処理して隣接する要素を比較し、結果のすべてのブール値を比較するのが最善だと思いますAND。しかし、それを実行するための最も Python 的な方法が何であるかはわかりません。

ベストアンサー1

使用itertools.groupby(見るレシピitertools):

from itertools import groupby

def all_equal(iterable):
    g = groupby(iterable)
    return next(g, True) and not next(g, False)

またはなしgroupby:

def all_equal(iterator):
    iterator = iter(iterator)
    try:
        first = next(iterator)
    except StopIteration:
        return True
    return all(first == x for x in iterator)

検討できる代替ワンライナーはいくつかあります。

  1. 入力をセットに変換し、1つまたは0つの項目(入力が空の場合)のみが含まれていることを確認します。

    def all_equal2(iterator):
        return len(set(iterator)) <= 1
    
  2. 最初の項目を除いた入力リストと比較する

    def all_equal3(lst):
        return lst[:-1] == lst[1:]
    
  3. リストの最初の項目が何回出現するかを数える

    def all_equal_ivo(lst):
        return not lst or lst.count(lst[0]) == len(lst)
    
  4. 最初の要素が繰り返されるリストと比較する

    def all_equal_6502(lst):
        return not lst or [lst[0]]*len(lst) == lst
    

しかし、次のような欠点もあります。

  1. all_equalおよびはall_equal2任意のイテレータを使用できますが、その他はシーケンス入力 (通常はリストやタプルなどの具体的なコンテナー) を受け取る必要があります。
  2. all_equalall_equal3違いが見つかったらすぐに停止します(「短絡False") ですが、最初の 2 つの要素だけを見て答えがわかる場合でも、すべての選択肢ではリスト全体を反復処理する必要があります。
  3. all_equal2コンテンツにはハッシュ可能リストのリストは、TypeErrorたとえば を発生させます。
  4. all_equal2(最悪の場合)all_equal_6502リストのコピーが作成されるため、メモリを 2 倍使用する必要があります。

Python 3.9では、perfplotすると、次のタイミングが得られます (低いほどRuntime [s]良い)。

最初の2つの要素が異なるリストの場合、groupbyが最も高速です差異のないリストの場合、count(l[0])が最も高速である。

おすすめ記事