I was messing around a bit with empty ndarrays and uncovered some unexpected behavior. Minimal working example:
import numpy as np
print(f"{np.empty(0)} :: {type(np.empty(0))}")
print(f"{[]} :: {type([])}")
print(f"internal -> {np.empty(0) == []} :: {type(np.empty == [])}")
external = np.empty(0) == []
print(f"external -> {external} :: {type(external)}")
Gives the output:
[] :: <class 'numpy.ndarray'>`
[] :: <class 'list'>
internal -> [] :: <class 'bool'>
external -> [] :: <class 'numpy.ndarray'>
I have three questions about this, and I suspect that the answers are probably related:
- Why does numpy return an empty array instead of a boolean when comparing an empty array with an empty list (or an empty tuple, or an empty dict, or an empty set, or another instance of an empty array)?
- Why don't we get the same type result when evaluating this inside of an f-string?
- Why does numpy not return an empty array when comparing an empty array with an empty string (
np.empty(0) == ''returns False)?
Based on the FutureWarning that gets raised when trying out the comparison to an empty string, I'm guessing that the answer to (1) probably has something to do with numpy performing an element-wise comparison between iterables with no elements, but I don't really get the details, nor why cases (2) and (3) seem to behave differently.
np.emptyitself to a empty list. That means two different__eq__methods are involved, not that the f-string itself has anything to do with the output.f'{np.empty(0)}'returns the same string.reprandstr.FutureWarningis present in NumPy 1.24.2, but not 1.26.4.