scikit-hep / awkward-0.x

Manipulate arrays of complex data structures as easily as Numpy.
BSD 3-Clause "New" or "Revised" License
215 stars 39 forks source link

AssertionError when Table is part of a list #235

Open jrueb opened 4 years ago

jrueb commented 4 years ago

I have a list of elements and I need to see if None is part of that list, so I do

None in elements

But if elements contains an awkward.Table I get an AssertionError:

None in [awkward.Table({}), None]

I would like to be able to use in even for lists sometimes containing Tables.

jrueb commented 4 years ago

I noticed the above example is actually raising yet another, different AssertionError then the one I get from my usecase. My usecase raises the error following this one:

None in [awkward.Table({"jagged": awkward.fromiter([[1,2],[3]])})]

Also I noticed a ValueError gets raised in case of this one

None in [awkward.Table({"flat": [1,2]})]
jpivarski commented 4 years ago

Implementing __contains__ (called by the in operator) would be a good idea, but it hasn't been done. If you have a MaskedArray, BitMaskedArray, or IndexedMaskedArray, you can get this information via

array.boolmask(maskedwhen=True).any()   # True if it contains `None`

If you don't have a MaskedArray, BitMaskedArray, or IndexedMaskedArray, the value can never be None.

jrueb commented 4 years ago

I'm not sure if I understand your answer correctly. I'm not interested if there is None inside my awkward object. All I'm doing is None and standard python lists. However these lists might contain awkward objects, but the contents of those objects are irrelevant for me.

jpivarski commented 4 years ago

Oh, I did misunderstand. Checking for None in a plain Python list calls == on each element, and == on an array—whether NumPy or Awkward—is a ufunc. If you do this with a NumPy array, it also fails, though the error message is better:

>>> None in [numpy.array([[1, 2], [3, 4]]), None]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Awkward should fail as gracefully as that.

To solve your problem, though, you'll want something like

any(None is x for x in that_list)
jrueb commented 4 years ago

Ah, you are right. I was testing it on numpy with

None in [np.array([])]

which works.