Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pythonic way to convert variable to list

Tags:

I have a function whose input argument can either be an element or a list of elements. If this argument is a single element then I put it in a list so I can iterate over the input in a consistent manner.

Currently I have this:

def my_func(input):
    if not isinstance(input, list): input = [input]
    for e in input:
        ...

I am working with an existing API so I can't change the input parameters. Using isinstance() feels hacky, so is there a proper way to do this?

like image 444
hoju Avatar asked Sep 13 '09 02:09

hoju


People also ask

How do you convert a Frozenset to a list?

Convert a frozenset to a list. The Python frozenset object is similar to a set but is immutable. Therefore, we cannot modify the elements of a frozenset. We can convert this type of set too, using list().

How do you convert data into a list in Python?

Typecasting to list can be done by simply using list(set_name) . Using sorted() function will convert the set into list in a defined order.

Can you convert a string to a list in Python?

Python String is a sequence of characters. We can convert it to the list of characters using list() built-in function. When converting a string to list of characters, whitespaces are also treated as characters. Also, if there are leading and trailing whitespaces, they are part of the list elements too.


1 Answers

Typically, strings (plain and unicode) are the only iterables that you want to nevertheless consider as "single elements" -- the basestring builtin exists SPECIFICALLY to let you test for either kind of strings with isinstance, so it's very UN-grotty for that special case;-).

So my suggested approach for the most general case is:

  if isinstance(input, basestring): input = [input]
  else:
    try: iter(input)
    except TypeError: input = [input]
    else: input = list(input)

This is THE way to treat EVERY iterable EXCEPT strings as a list directly, strings and numbers and other non-iterables as scalars (to be normalized into single-item lists).

I'm explicitly making a list out of every kind of iterable so you KNOW you can further on perform EVERY kind of list trick - sorting, iterating more than once, adding or removing items to facilitate iteration, etc, all without altering the ACTUAL input list (if list indeed it was;-). If all you need is a single plain for loop then that last step is unnecessary (and indeed unhelpful if e.g. input is a huge open file) and I'd suggest an auxiliary generator instead:

def justLoopOn(input):
  if isinstance(input, basestring):
    yield input
  else:
    try:
      for item in input:
        yield item
    except TypeError:
      yield input

now in every single one of your functions needing such argument normalization, you just use:

 for item in justLoopOn(input):

You can use an auxiliary normalizing-function even in the other case (where you need a real list for further nefarious purposes); actually, in such (rarer) cases, you can just do:

 thelistforme = list(justLoopOn(input))

so that the (inevitably) somewhat-hairy normalization logic is just in ONE place, just as it should be!-)

like image 75
Alex Martelli Avatar answered Sep 28 '22 07:09

Alex Martelli