Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Wednesday, February 10, 2016

Python: Get first element of list potentially containing sublists

Python: Get first element of list potentially containing sublists


I'm looking for the first element of a Python list potentially containing either numbers (integer or float), or many levels of nested sublists containing the same. In these examples, let's suppose I am always looking for the number '1'. If the list contains no sublists, we have:

>>> foo = [1,2,3]  >>> foo[0]  1  

If the list contains one sublist, and I know this information, I can again obtain 1 with

>>> foo = [[1,2],[3,4]]  >>> foo[0][0]  1  

Similarly if the first element of my list is a list containing a list:

>>> foo = [[[1,2],[3,4]],[[5,6],[7,8]]]  >>> foo[0][0][0]  1  

Is there a general way to get the first integer or float in foo, without resorting to calling a function recursively until drilling down to a value of foo[0] that is no longer a list?

Answer by R Nar for Python: Get first element of list potentially containing sublists


create a simple, recursive function:

>>> def getFirst(l):      return l[0] if not isinstance(l[0],list) else getFirst(l[0])    >>> getFirst([1,2,3,4])  1  >>> getFirst([[1,2,3],[4,5]])  1  >>> getFirst([[[4,2],12,[1,3]],1])  4  

this will return l[0] if l[0] is anything but a list. else, it will return the first item of l[0] recursively

Answer by Adam Smith for Python: Get first element of list potentially containing sublists


The general-case answer for this is "Fix your data structure." Lists are supposed to be homogeneous, e.g. every element of the list should have the same type (be that int or list of ints or list of lists of ints or etc).

The special case here would be to recurse until you find a number and return it.

def foo(lst):      first_el = lst[0]      if isinstance(first_el, (float, int)):          return first_el      else:          return foo(first_el)  

Answer by Tyler Crompton for Python: Get first element of list potentially containing sublists


There shouldn't be any need for recursion. Assuming that you are always working with lists and ints, this should work perfectly well for you.

foo = [[[1,2],[3,4]],[[5,6],[7,8]]]    result = None  while True:      try:          result = foo[0]      except TypeError:          break  

Unlike the other answers, this asks for forgiveness rather than for permission, which is a bit more Pythonic.

If you really want to be Pythonic, you could define a function like as follows. However, this would admittedly be overkill given your specification.

def first_scalar(foo):      result = None      while True:          try:              result = next(iter(foo))          except TypeError:              return result  

Note that it returns None if the argument is not an iterable. The same applies for the first segment of code.

Note that this doesn't work if the if the deepest "left-most" child list is empty. To account for this, you'll need to totally flatten the list.

def _flatten(foo):      try:          for item in foo:              yield from flatten(foo)      except TypeError:          yield foo    def flatten(foo):      for item in foo:          yield from _flatten(foo)    def first_scalar(foo):      return next(flatten(foo))  

Note that the above must be written in at least Python 3.3.

The following code is for earlier versions of Python.

def _flatten(foo):      try:          for item in foo:              for subitem in _flatten(foo):                  yield subitem      except TypeError:          yield foo    def flatten(foo):      for item in foo:          for subitem in _flatten(foo):              yield subitem  

Answer by Felk for Python: Get first element of list potentially containing sublists


You can just "dive in", without any recursion:

lst = [[1, 2], [3, 4]]  first = lst  while isinstance(first, list):      first = first[0]  

Answer by brunodea for Python: Get first element of list potentially containing sublists


If you really want to avoid any loops or recursion, there is an ugly workaround. Transform the list to a string and then remove the list-specific chars:

','.join(map(str,foo)).replace('[','').replace(']','').replace(' ','').split(',')  

Of course it only works if the list is composed by strings or integers. If the objects in the list are custom, you would have to transform them to string. But, since there is an unknown number of sublists, you would have to use recursion, so using this workaround wouldn't make sense.

Another thing, maybe the elements of the list and sublists have the same chars as the list-specific ones, such as '[' or ',', so that would also be a problem.

In short, this is a bad workaround that only works for sure if the list and sublists are composed of numbers. Otherwise, using some kind of recursion is most probably necessary.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.