views:

57

answers:

1

Possible Duplicate:
Flatten (an irregular) list of lists in Python

How would I go about flattening a list in Python that contains both iterables and noniterables, such as [1, [2, 3, 4], 5, [6]]? The result should be [1,2,3,4,5,6], and lists of lists of lists (etc.) are certain never to occur.

I have tried using itertools.chain, etc., but they seem only to work on lists of lists. Help!

+1  A: 

So you want to flatten only 1 or 2 levels, not recursively to further depts; and only within lists, not other iterables such as strings, tuples, arrays... did I get your specs right? OK, if so, then...:

def flat2gen(alist):
  for item in alist:
    if isinstance(item, list):
      for subitem in item: yield subitem
    else:
      yield item

If you want a list result, list(flat2gen(mylist)) will produce it.

Hope this is trivially easy for you to adapt if your actual specs are minutely different!

Alex Martelli
Perfect; thanks! Preliminary trials with timeit suggest it may be a touch too slow, but I see little alternative given the situation.
Ignis Umbrae
@etotheipi, what's a typical, meaningful "benchmark `alist`" for your app, what timings are you getting for it (and on what platform exactly) and which better ones would suffice? It may be possible to tweak and optimize in many ways, but not in a vacuum, so these things are all needed (ideally in a new question so as to allow spacious A's for answers, rather than a crammed comment-threads; also ideally with a few typical "benchmark `alist`"s, not just 1).
Alex Martelli
Don't mind what I said -- I hadn't converted the units of timeit, and I falsely thought the function was too slow (doh!). In actuality, it takes about 56 microseconds on my machine to chew through input 15x larger than practically sized input (8-10 items at most), so it's just what I need. Thanks again!
Ignis Umbrae