7

In python, strings can be looped/iterated, as list, tuples, etc can be. We have the same for dict and bytes. So, using isinstance vs any collections.abc class gives True on list, bytes, dicts, etc.

I'm searching for an elegant way to check if I have received a list-like argument to a method: list, tuple, set, numpy array, pandas Series, etc?

Do you have any suggestion which is not test if iterable but neither string nor dict, etc.

I'm really trying to match the non-developer intuitive understanding of what a list is.

7
  • What are you considering to be "list-like"? What traits specifically are you wanting to include, and what are you wanting to exclude? Why exclude strings but include tuples? Commented Jan 24, 2020 at 15:32
  • Check if it's an instance and not type(your_var) not in [str, bytes] Commented Jan 24, 2020 at 15:32
  • 2
    @Carcigenicate List like is the intuitive understanding of a list: some elements which can be listed with bullet points, like any non developer will understand. If I ask to my mom if "toto" is a list, she will say no... Commented Jan 24, 2020 at 15:36
  • 1
    Considering that's a fairly arbitrary separation, I think manually hardcoding types is as good as you're going to get. If there were a pattern of methods used etc, you could find a specific base-class to check. That isn't the case here though. Commented Jan 24, 2020 at 15:37
  • 1
    Well, @Carcigenicate, I think you're right. Just wanting to find something matching intuition, but I think it does not exists. That's life ;-) Commented Jan 24, 2020 at 15:38

3 Answers 3

3

Another option would be checking if your variable is an Iterable, but manually exclude what you think should not be accepted:

from collections.abc import Iterable

excluded_types = (str, dict)
if isinstance(obj, Iterable) and not isinstance(obj, excluded_types):
  do_something()

But you should define what iterable behavior you are expecting to consider something "list-like".

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, but that's what I want to avoid. See my other comments. Conclusion seems to be that it is not possible.
1

You could create your own function for this:

import numpy as np
import pandas as pd

def is_list_like(obj):
    valid_types = (list, tuple, set, np.ndarray, pd.Series)
    return isinstance(obj, valid_types)

This works for any arbitrary definition of "list-like" you prefer to use - just add/remove types from the valid_types tuple.

3 Comments

Well, why not. That's more or less what I do now. I've commented it on the question's comments. I really think that it is not possible in python, but I just want to be sure... Thanks anyway.
I see what you mean, but I don't think there's a better, "built-in" way other than hardcoding the types you want to be list-like. You say sets are list-like, but from an implementation perspective they are much more similar to dictionaries. The fact that mylist[0] and mydict[0] both call obj.__getitem__(0) means that, even on the implementation level, there's not a simple, clear-cut distinction between list-like and not.
True @jfaccioni. Indeed, implementation is another story, where I got stuck. I'll continue with the "inelegant" way :-(
0

Assuming you are using numpy, you can construct an array and check its dimensions. Anything with ndim of zero almost fits your definition.

>>> import numpy as np
>>> f = np.asarray("hello") # string
>>> f.ndim
0
>>> f=np.asarray({1:2,3:4}) # dict
>>> f.ndim
0
>>> f=np.asarray([1,2,3,4]) # list
>>> f.ndim
1
>>> f=np.asarray((1,2,3,4)) # tuple
>>> f.ndim
1

Unfortunately, this does not appear to work for set.

>>> f=np.asarray({1,2,3,4}) # set
>>> f.ndim
0

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.