mog
mog

Reputation:

What is the pythonic way of checking if an object is a list?

I have a function that may take in a number or a list of numbers. Whats the most pythonic way of checking which it is? So far I've come up with try/except block checking if i can slice the zero item ie. obj[0:0]

Edit:

I seem to have started a war of words down below by not giving enough info. For completeness let me provide more details so that I may pick and get the best answer for my situation:

I'm running Django on Python 2.6 and I'm writing a function that may take in a Django model instance or a queryset object and perform operations on it one of which involves using the filter 'in' that requires a list (the queryset input), or alternately if it is not a list then I would use the 'get' filter (the django get filter).

Upvotes: 10

Views: 930

Answers (7)

Daren Thomas
Daren Thomas

Reputation: 70324

I don't want to be a pest, BUT: Are you sure the query set/object is a good interface? Make two functions, like:

def fobject(i):
   # do something

def fqueryset(q):
   for obj in q:
       fobject( obj )

Might not be the pythonic way to discern an int from a list, but seems a far better design to me.

Reason being: Your function should be working on ducks. As long as it quacks, whack it. Actually picking the duck up, turning it upside down to check the markings on the belly before choosing the right club to whack it is unpythonic. Sorry. Just don't go there.

Upvotes: 2

Georg Schölly
Georg Schölly

Reputation: 126105

You don't.

This works only for Python >= 2.6. If you're targeting anything below use Alex' solution.

Python supports something called Duck Typing. You can look for certain functionality using the ABC classes.

import collections
def mymethod(myvar):
    # collections.Sqeuence to check for list capabilities
    # collections.Iterable to check for iterator capabilities
    if not isinstance(myvar, collections.Iterable):
        raise TypeError()

Upvotes: 11

Anurag Uniyal
Anurag Uniyal

Reputation: 88757

I think the way OP is doing, checking if it supports what he wants, is ok.

Simpler way in this scenario would be to not check for list which can be of many types depending on definition, you may check if input is number, do something on it else try to use it as list if that throws exception bail out.

e.g you may not want iterate over list but just wanted to append something to it if it is list else add to it

def add2(o):
    try:
        o.append(2)
    except AttributeError:
        o += 2

l=[]
n=1
s=""
add2(l)
add2(n)
add2(s) # will throw exception, let the user take care of that ;)

So bottom line is answer may vary depending on what you want to do with object

Upvotes: 0

Alex Martelli
Alex Martelli

Reputation: 881665

In such situations, you normally need to check for ANY iterable, not just lists -- if you're accepting lists OR numbers, rejecting (e.g) a tuple would be weird. The one kind of iterable you might want to treat as a "scalar" is a string -- in Python 2.*, this means str or unicode. So, either:

def isNonStringIterable(x):
  if isinstance(x, basestring):
    return False
  try: iter(x)
  except: return False
  else: return True

or, usually much handier:

def makeNonStringIterable(x):
  if isinstance(x, basestring):
    return (x,)
  try: return iter(x)
  except: return (x,)

where you just go for i in makeNonStringIterable(x): ...

Upvotes: 21

Dominic Bou-Samra
Dominic Bou-Samra

Reputation: 15416

Just use the type method? Or am I misinterpreting the question

if type(objectname) is list:
  do something
else:
  do something else :P

Upvotes: -3

Vince
Vince

Reputation: 7638

if isinstance(your_object, list):
  print("your object is a list!")

This is more Pythonic than checking with type.

Seems faster too:

>>> timeit('isinstance(x, list)', 'x = [1, 2, 3, 4]')
0.40161490440368652
>>> timeit('type(x) is list', 'x = [1, 2, 3, 4]')
0.46065497398376465
>>> 

Upvotes: 13

sth
sth

Reputation: 229593

You can use isinstance to check a variables type:

if isinstance(param, list):
   # it is a list
   print len(list)

Upvotes: 1

Related Questions