web-dev-qa-db-ja.com

Pythonリストのすべての要素が同じタイプかどうかを確認する

pythonでは、可能であればすべての要素を個別にチェックせずに)リストの要素が同じタイプであるかどうかを確認する方法はありますか?

たとえば、このリストのすべての要素が整数であることを確認する関数が必要です(明らかにfalseです)。

x=[1, 2.5, 'a']

def checkIntegers(x):
    # return true if all elements are integers, false otherwise
39
linello

allisinstance と組み合わせて使用​​してみてください:

_all(isinstance(x, int) for x in lst)
_

望ましい場合は、isinstanceを使用して複数のタイプをチェックすることもできます。

_all(isinstance(x, (int, long)) for x in lst)
_

これは継承されたクラスも同様にピックアップするというわけではありません。例えば。:

_class MyInt(int):
     pass

print(isinstance(MyInt('3'),int)) #True
_

必要な場合整数に制限する必要がある場合は、all(type(x) is int for x in lst)を使用できます。しかし、それは[〜#〜] very [〜#〜]まれなシナリオです。


これで記述できる楽しい関数は、他のすべての要素が同じ型である場合、シーケンスの最初の要素の型を返す関数です。

_def homogeneous_type(seq):
    iseq = iter(seq)
    first_type = type(next(iseq))
    return first_type if all( (type(x) is first_type) for x in iseq ) else False
_

これは任意の反復可能オブジェクトに対して機能しますが、プロセスで「イテレータ」を消費します。

共通の基底のセットを返す同じ静脈内の別の楽しい関数:

_import inspect
def common_bases(seq):
    iseq = iter(seq)
    bases = set(inspect.getmro(type(next(iseq))))
    for item in iseq:
        bases = bases.intersection(inspect.getmro(type(item)))
        if not bases:
           break
    return bases
_

90
mgilson

any() を使用すると、リスト全体を走査する必要はありません。 intまたはlongではないオブジェクトが見つかったらすぐにブレークします。

>>> not any(not isinstance(y,(int,long)) for y in [1,2,3])
True
>>> not any(not isinstance(y,(int,long)) for y in [1,'a',2,3])
False
3
>>> def checkInt(l):
    return all(isinstance(i, (int, long)) for i in l)

>>> checkInt([1,2,3])
True
>>> checkInt(['a',1,2,3])
False
>>> checkInt([1,2,3,238762384762364892364])
True
2
Inbar Rose

リストが同種の要素で構成されているかどうかを確認する最も簡単な方法は、itertoolsモジュールのgroupby関数を使用することです。

from itertools import groupby
len(list(groupby(yourlist,lambda i:type(i)))) == 1

Th lenが1と異なる場合は、リスト内で異なる種類のタイプが見つかったことを意味します。これには、シーケンス全体を実行するという問題があります。遅延バージョンが必要な場合は、そのための関数を作成できます。

def same(iterable):
    iterable = iter(iterable)
    try:
        first = type(next(iterable))
        return all(isinstance(i,first) for i in iterable)
    except StopIteration:
        return True

この関数は最初の要素の型を保存し、リスト内の要素の1つで別の型を見つけるとすぐに停止します。

このメソッドは両方とも型に非常に敏感であるため、異なるintとfloatとして認識されますが、これはリクエストに到達できる限り近いものでなければなりません。

編集:

mgilsonが示唆するように、forサイクルをallへの呼び出しに置き換えました

voidイテレータの場合は、すべての関数bulitinの動作と一致するようにTrueを返します

1
EnricoGiampieri

Map()、type()、set()の組み合わせを使用して、すでに与えられたいくつかの答えを組み合わせることで、私見ではなく読みやすい答えが得られます。型の多型をチェックしないという制限は問題ありません。また、最も計算効率のよい答えではありませんが、すべての要素が同じタイプであるかどうかを簡単に確認できます。

# To check whether all elements in a list are integers
set(map(type, [1,2,3])) == {int}
# To check whether all elements are of the same type
len(set(map(type, [1,2,3]))) == 1
1
user1556435

サブクラスを除外する場合は、type()を使用することもできます。 isinstance()type()の違い を参照してください。

_>>> not any(not type(y) is int for y in [1, 2, 3])
True
>>> not any(not type(y) == int for y in [1, 'a', 2.3])
False
_

あなたはしたくないかもしれませんが、これはより壊れやすいので。 yの型をintのサブクラスに変更すると、このコードは壊れますが、isinstance()は引き続き機能します。

メモリには_<type 'int'>_が1つしかないため、isを使用しても構いません。したがって、同じタイプであれば同じIDを返す必要があります。

0
Mark Mikofski