0

This is not converting a 2d list to a 1d list. This is converting a list element (which happens to be a list) to multiple elements within the containing list. The input is not a list of lists.

I have a list like the following:

x = [1, [2,3,4], 5,....]

I want to convert it to this:

x = [1, 2, 3, 4, 5] 

I know something like the following will work:

y = []
for _ in x:
  if isinstance(_, list):
   for i in _:
     y.append(i)
  else:
    y.append(_)

But was hoping there was some more pythonic way like the following (obviously won't work):

x = [2, _ for _ in [2,3,4], 5]
user2263572
  • 5,435
  • 5
  • 35
  • 57
  • Side note, a single underscore `_` is usually reserved [for throwaway variables](https://stackoverflow.com/a/5893186/4518341), so using it here is confusing. – wjandrea Jan 13 '21 at 01:43
  • Side note, instead of `for i in _: y.append(i)`, it's simpler to do `y.extend(_)`. – wjandrea Jan 13 '21 at 01:44
  • Does this answer your question? [Flatten an irregular list of lists](https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists) – wjandrea Jan 13 '21 at 01:46
  • @wjandrea, it doesn't directly answer the question. The code in my question isn't really different than any of those answers. The answer seems to be "There is no way to flatten a single list element in place" or the answer I accepted which is "here is a clever way to solve this in python" although not exactly what I was attempting to do. – user2263572 Jan 13 '21 at 03:10
  • @wjandrea the point was the "_" would be a throwaway variable that temporarily stores the list element. No different than the following [_ for _ in [2,3,4]]. – user2263572 Jan 13 '21 at 03:13
  • "Throwaway" means you don't actually use it. Where you reference it later, that means it's not a throwaway name. So I would change it to something like `for item in x: if isinstance(item, list): ...`. [This answer](https://stackoverflow.com/a/5893946/4518341) has some examples of actual throwaways. – wjandrea Jan 13 '21 at 03:21

2 Answers2

1

You can do it like this (making a list homogeneous and then combining the elements):

>>> x = [1, [2, 3, 4], 5]
>>> sum([[i] if not isinstance(i, list) else i for i in x], [])
[1, 2, 3, 4, 5]

Another solution with functool.reduce:

>>> from functools import reduce
>>> a = [1, [2, 3, 4], 5]
>>> reduce(lambda x, y: [x] + y if not isinstance(x, list) else (x + [y] if not isinstance(y, list) else x + y), a)
[1, 2, 3, 4, 5]
Jarvis
  • 8,494
  • 3
  • 27
  • 58
  • This will work. If looping over all list elements in the only way to do this, I will mark this as the accepted answer. – user2263572 Jan 13 '21 at 00:03
  • @user2263572 I added another solution with `reduce` which recursively processes the list with no _explicit_ loop – Jarvis Jan 13 '21 at 00:42
0

Let me do you one better. Let's assume that the elements themselves can be lists containing other elements. for example something like this: [1,[2,3,[4,5,6],[[4,5],6]]]

You can do a dfs (depth-first-search) to collapse them into a single list

def dfs(elem):
  if isinstance(elem, int):
    return [elem]
  else:
    ret = []
    
    for i in elem:
      ret += dfs(i)
    return ret

If you just want it for a single depth and really pythonic, then this will do:

sum([[i] if isinstance(i, int) else i for i in x],[])
feverdreme
  • 467
  • 4
  • 12