It seems the conversation has confused two related concepts: 1) The default bool() implementation (Truthiness) -- this is what the OP said was recommended by PEP 8: "For sequences, (strings, lists, tuples), use the fact that empty sequences are false:" -- there is some debate about that whether this is a good recommendation or not, but i don't think that's the OPs point. Rather:
2) That there is no standard way to explicitly test containers for "emptiness" - - there is only length, with the assumption that len(something) == 0 or not len(something) is a good way to test for emptiness. I still don't see why length is not perfectly adequate, but i wonder if there are any "containers" i.e.things that could be empty, in the std lib that don't support length. Looking in the ABCs, a Container is something that supports `in`, and a Sized is something that supports len()-- so in theory, there could be a Container that does not have a length. Are there any in the std lib? Perhaps the ABCs are instructive in another way here -- if we were to add a __empty__ or some such dunder, what ABC would require it? Container? or yet another one-method ABC? -CHB On Tue, Aug 24, 2021 at 8:39 PM David Mertz, Ph.D. <david.me...@gmail.com> wrote: > I wanted to do a survey of various "aggregates" in Python to see if any > stand out as making the usual `if stuff: ...` troublesome. I wrote a > little script at > https://github.com/DavidMertz/LanguagePractice/blob/main/python/aggregates.py > . > > I'm being deliberately vague about an "aggregate." It might not be a > collection strictly speaking, but it is something that might seems to > "contain" values in some sense. Basically, I think that standard library > and built-in stuff behaves per PEP8. Some other libraries go their own > way. I throw in a linked-list implementation I found on PyPI. I've never > used it beyond this script; but per what it is, it cannot implement `len()` > on O(1) (well, it *could* if it does extra bookkeeping; but then it's kinda > a different thing). > > In NumPy land, the np.empty vs. np.zeros case is another oddball. On my > system, my memory happened to have some prior value that wasn't zero; that > could vary between runs, in principle. > > These are the results: > > Expr: '' | Value: '' > Truth: False | Length: 0 > Expr: list() | Value: [] > Truth: False | Length: 0 > Expr: tuple() | Value: () > Truth: False | Length: 0 > Expr: dict() | Value: {} > Truth: False | Length: 0 > Expr: set() | Value: set() > Truth: False | Length: 0 > Expr: bytearray() | Value: bytearray(b'') > Truth: False | Length: 0 > Expr: bytearray(1) | Value: bytearray(b'\x00') > Truth: True | Length: 1 > Expr: bytearray([0]) | Value: bytearray(b'\x00') > Truth: True | Length: 1 > Expr: array.array('i') | Value: array('i') > Truth: False | Length: 0 > Expr: array.array('i', []) | Value: array('i') > Truth: False | Length: 0 > Expr: Nothing() | Value: EmptyNamedTuple() > Truth: False | Length: 0 > Expr: deque() | Value: deque([]) > Truth: False | Length: 0 > Expr: deque([]) | Value: deque([]) > Truth: False | Length: 0 > Expr: ChainMap() | Value: ChainMap({}) > Truth: False | Length: 0 > Expr: queue.Queue() | Value: <queue.Queue object at 0x7f0940dd2190> > Truth: True | Length: No length > Expr: asyncio.Queue() | Value: <Queue at 0x7f0940dd2190 maxsize=0> > Truth: True | Length: No length > Expr: multiprocessing.Queue() | Value: <multiprocessing.queues.Queue > object at 0x7f0940dd2190> > Truth: True | Length: No length > Expr: np.ndarray(1,) | Value: array([5.e-324]) > Truth: True | Length: 1 > Expr: np.ndarray((1,0)) | Value: array([], shape=(1, 0), dtype=float64) > Truth: False | Length: 1 > Expr: np.empty((1,)) | Value: array([5.e-324]) > Truth: True | Length: 1 > Expr: np.zeros((1,)) | Value: array([0.]) > Truth: False | Length: 1 > Expr: np.zeros((2,)) | Value: array([0., 0.]) > Truth: No Truthiness | Length: 2 > Expr: np.ones((1,)) | Value: array([1.]) > Truth: True | Length: 1 > Expr: np.ones((2,)) | Value: array([1., 1.]) > Truth: No Truthiness | Length: 2 > Expr: pd.Series() | Value: Series([], dtype: float64) > Truth: No Truthiness | Length: 0 > Expr: pd.DataFrame() | Value: Empty DataFrame > Truth: No Truthiness | Length: 0 > Expr: xr.DataArray() | Value: <xarray.DataArray ()> > Truth: True | Length: No length > Expr: linkedadt.LinkedList() | Value: <linkedadt.LinkedList object at > 0x7f08d8d77f40> > Truth: False | Length: 0 > > > > -- > Keeping medicines from the bloodstreams of the sick; food > from the bellies of the hungry; books from the hands of the > uneducated; technology from the underdeveloped; and putting > advocates of freedom in prisons. Intellectual property is > to the 21st century what the slave trade was to the 16th. > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/XIQPNWDNRDGO3NOIY5KUHZ5CMR67TRWS/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6QF7NPIB2ZODZWAR7VKVZJHSKADTORNG/ Code of Conduct: http://python.org/psf/codeofconduct/