Есть ли более быстрый способ проверить, являются ли все объекты в списке python экземплярами int (или каким-либо другим классом), чем перебирать список?

avatar
caffreyd
8 апреля 2018 в 03:29
157
2
0

Я хочу убедиться, что все объекты, содержащиеся в данном списке, являются экземплярами int (или какого-либо другого класса или набора классов).

Например, я могу сделать так:

my_list = [1, 2, 3, 4]

for i in my_list:
  if not isinstance(i, int):
    raise Exception('Found a non-int!')

Есть ли более быстрый способ, чем перебор списка? Мне нужно расширить класс списка, чтобы он содержал набор каждого добавленного класса или что-то в этом роде?

Источник
Bill Bell
8 апреля 2018 в 18:26
1

Я уже должен был понять, что стоит делать тайминги. Я обновил свой ответ.

Ответы (2)

avatar
Bill Bell
8 апреля 2018 в 03:39
2

Попробую еще раз. Мой первоначальный ответ был кратким, но, увы, НЕПРАВИЛЬНЫМ. На ту же тему мне пришло в голову заменить конструкцию с участием lambda. Правильный результат. Возможно, это позволило бы быстрее достичь требуемых результатов?

>>> my_list = [0,2,3,4]
>>> all(map(lambda x: type(x)==int, my_list))
True

Соответственно я рассчитал время двух подходов:

s = '''\
my_list = [0, 2, 3, 4]
for i in my_list:
    if not isinstance(i, int):
        raise Exception('Found a non-int!')'''

print (timeit.timeit(s))

s = '''\
my_list = [0,2,3,4]
all(map(lambda x: type(x)==int, my_list))'''

print (timeit.timeit(s))

со следующим выводом:

0.6864084666728032
1.3789049683458745

Подход, основанный на map, не только не быстрее, но и занимает в два раза больше времени. Неустрашимый (или свиноголовый, если хотите) я подумал, что может быть какое-то время установки, которое объясняет производительность «моего» подхода. Поэтому я попробовал гораздо больший список.

s = '''\
my_list = list(range(2000))
for i in my_list:
    if not isinstance(i, int):
        raise Exception('Found a non-int!')'''

print (timeit.timeit(s))

s = '''\
my_list = list(range(2000))
all(map(lambda x: type(x)==int, my_list))'''

print (timeit.timeit(s))

со следующими результатами:

305.03338925738615
478.1060787659975

И снова подход с использованием map и lambda намного медленнее.


(Я постараюсь забыть, что написал это.)

Кратко:

>>> my_list = [1,2,3,4]
>>> all(map(int, my_list))
True

В Python список может содержать элементы любого типа.

>>> a_list = [1, 'b', 5, 7]
avatar
Cuong Vu
8 апреля 2018 в 03:38
3

Вы можете комбинировать all() с isinstance() следующим образом

a = [1, 2, 3, 4]

# return true
print(all(isinstance(i, int) for i in a))

b = [1, 2, 3, 4.5]

# return false
print(all(isinstance(i, int) for i in b))

#for list of instances
c = ['hello', 2, 3, 4]

#return true
print(all(isinstance(i, (int, str)) for i in c))