Подтвердить что ты не робот

Python проверяет, одинаковы ли все элементы списка

Как можно проверить python (не проверяя индивидуально каждый элемент, если это возможно), если элементы списка имеют один и тот же тип?

Например, я хотел бы иметь функцию, чтобы проверить, что каждый элемент этого списка является целым (что явно ложно):

x=[1, 2.5, 'a']

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

Ответ 1

Попробуйте использовать all в сочетании с isinstance:

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). Но это редкий сценарий ОЧЕНЬ.


Функция fun, которую вы могли бы написать, - это та, которая возвращает тип первого элемента в последовательности, если все остальные элементы одного типа:

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

Это будет работать для любых произвольных итераций, но в этом процессе будут использоваться итераторы.

Другая функция fun в том же вене, которая возвращает набор общих оснований:

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

Ответ 2

Используя 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

Ответ 4

Самый простой способ проверить, состоит ли список из однородных элементов, может быть с функцией groupby модуля itertools:

from itertools import groupby
len(list(groupby(yourlist,lambda i:type(i)))) == 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

Эта функция хранит тип первого элемента и останавливается, как только он находит другой тип в одном из элементов в списке.

Оба эти метода сильно чувствительны к типу, поэтому он будет видеть как разные int и float, но это должно быть как можно ближе к вашему запросу

ИЗМЕНИТЬ:

заменил цикл for на вызов всем, как было предложено mgilson

в случае итератора void он возвращает True, чтобы быть совместимым с поведением всей функции bulitin

Ответ 5

Объединив некоторые из уже полученных ответов, используя комбинацию map(), type() и set(), вы получите наиболее читаемый ответ imho. Предполагая, что ограничение не проверяет полиморфизм типа, это нормально. Также не самый эффективный с точки зрения вычислений ответ, но он позволяет легко проверить, являются ли все элементы одного и того же типа.

# 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

Ответ 6

Вы также можете использовать 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() будет работать.

Хорошо использовать is, потому что в памяти есть только один <type 'int'>, поэтому они должны возвращать тот же идентификатор, если они являются одним и тем же типом.

Ответ 7

    def c(x):
         for i in x:
             if isinstance(i,str):
                   return False
             if isinstance(i,float):
                   return False

          return True

Ответ 8

Я предпочитаю использовать карту для такого случая:

from types import IntType
In [21]: map((lambda x: isinstance(x, IntType)), x)
   Out[21]: [True, False, False]