( EDIT : для включения более общего и, возможно, более чистого подхода)
Один из способов обойти это - реализовать NumPy безопасную версию in
:
import numpy as np
def in_np(x, items):
for item in items:
if isinstance(x, np.ndarray) and isinstance(item, np.ndarray) \
and x.shape == item.shape and np.all(x == item):
return True
elif isinstance(x, np.ndarray) or isinstance(item, np.ndarray):
pass
elif x == item:
return True
return False
x = np.array([1, 1])
a = [x, 1]
for y in (x, 0, 1, x + 1, np.array([1, 1, 1])):
print(in_np(y, a))
# True
# False
# True
# False
# False
Или, что еще лучше, написать версию in
с произвольным сравнением (возможно, с поведением по умолчанию in
), а затем использовать np.array_equal()
, который имеет semanti c, который соответствует ожидаемому поведению ==
. В коде:
import operator
def in_(x, items, eq=operator.eq):
for item in items:
if eq(x, item):
return True
return False
x = np.array([1, 1])
a = [x, 1]
for y in (x, 0, 1, x + 1, np.array([1, 1, 1])):
print(in_(y, a, np.array_equal))
# True
# False
# True
# False
# False
Наконец, обратите внимание, что items
может быть любым итеративным, но сложность операции не будет O(1)
для контейнеров хеширования, таких как set()
, хотя он все равно будет давать правильные результаты:
print(in_(1, {1, 2, 3}))
# True
print(in_(0, {1, 2, 3}))
# False
in_(1, {1: 2, 3: 4})
# True
in_(0, {1: 2, 3: 4})
# False