Python检查列表中的所有元素是否都属于同一类型

python如何检查(如果可能,不单独检查每个元素)列表中的元素是否属于同一类型?

例如,我想要一个函数来检查此列表中的每个元素是否为整数(显然是错误的):

x=[1, 2.5, 'a']

def checkIntegers(x):
    # return true if all elements are integers, false otherwise
linello asked 2020-08-06T10:47:41Z
8个解决方案
97 votes

尝试结合使用all(type(x) is int for x in lst)all(type(x) is int for x in lst)

all(isinstance(x, int) for x in lst)

如果需要,您甚至可以使用all(type(x) is int for x in lst)检查多种类型:

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)。但这是非常罕见的情况。


您可以编写一个有趣的函数,如果所有其他元素都是同一类型,它将返回序列中第一个元素的类型:

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

mgilson answered 2020-08-06T10:48:13Z
4 votes

使用int,无需遍历整个列表。 只要找到不是intlong的对象,就立即断开:

>>> 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
Ashwini Chaudhary answered 2020-08-06T10:48:33Z
2 votes
>>> 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
Inbar Rose answered 2020-08-06T10:48:48Z
2 votes

使用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
user1556435 answered 2020-08-06T10:49:08Z
1 votes

检查列表是否由同类元素组成的最简单方法是使用itertools模块的groupby函数:

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

如果len与一个不同,则意味着它在列表中找到了不同类型的类型。这具有贯穿整个序列的问题。如果您想要一个懒惰的版本,可以为此编写一个函数:

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

此函数存储第一个元素的类型,并在列表中的一个元素中找到其他类型后立即停止。

这两种方法对类型都非常敏感,因此它将看到不同的int和float,但这应尽可能接近您的请求

编辑:

按照mgilson的建议,将for周期替换为对所有人的调用

在void迭代器的情况下,它返回True与bulitin所有函数的行为一致

EnricoGiampieri answered 2020-08-06T10:49:55Z
0 votes

如果要排除子类,也可以使用is。 查看is<type 'int'>之间的区别:

>>> 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的子类,则此代码将中断,而is仍将起作用。

可以使用is,因为内存中只有一个<type 'int'>,所以如果它们是相同类型,则它们应该返回相同的标识。

Mark Mikofski answered 2020-08-06T10:50:25Z
-1 votes
    def c(x):
         for i in x:
             if isinstance(i,str):
                   return False
             if isinstance(i,float):
                   return False

          return True
raton answered 2020-08-06T10:50:40Z
-1 votes

我更喜欢在这种情况下使用map:

from types import IntType
In [21]: map((lambda x: isinstance(x, IntType)), x)
   Out[21]: [True, False, False]
Low Kian Seong answered 2020-08-06T10:51:00Z
translate from https://stackoverflow.com:/questions/13252333/python-check-if-all-elements-of-a-list-are-the-same-type