Flatten A List Of Strings And Lists Of Strings And Lists In Python
Solution 1:
The oft-repeated flatten
function can be applied to this circumstance with a simple modification.
from collections import Iterable
defflatten(coll):
for i in coll:
ifisinstance(i, Iterable) andnotisinstance(i, basestring):
for subc in flatten(i):
yield subc
else:
yield i
basestring
will make sure that both str
and unicode
objects are not split.
There are also versions which count on i
not having the __iter__
attribute. I don't know about all that, because I think that str
now has that attribute. But, it's worth mentioning.
(Please upvote the linked answer.)
Solution 2:
Using recursion.
def flatten(A):
rt = []
for i in A:
if isinstance(i,list): rt.extend(flatten(i))
else: rt.append(i)
return rt
Test:
>>> list_of_menuitems = ['image10', ['image00', 'image01'], ['image02', ['image0
3', 'image04']]]
>>> flattern(list_of_menuitems)
['image10', 'image00', 'image01', 'image02', 'image03', 'image04']
Solution 3:
The following works for strings (and would be easily adapted to other types):
defflatten_to_strings(listOfLists):
"""Flatten a list of (lists of (lists of strings)) for any level
of nesting"""
result = []
for i in listOfLists:
# Only append if i is a basestring (superclass of string)ifisinstance(i, basestring):
result.append(i)
# Otherwise call this function recursivelyelse:
result.extend(flatten_to_strings(i))
return result
flatten_to_strings(list_of_menuitems)
Out[2]: ['image10', 'image00', 'image01', 'image02', 'image03', 'image04']
Solution 4:
In one specialized case when none of the list items contains one of the following delimiters []'
, you can use the following hack. I have not profiled it, but it looks obvious that, this would have a better performance than the obvious and cleaner recursive solution.
>>> str(list_of_menuitems).translate(None,"[]'").split(',')
['image10', ' image00', ' image01', ' image02', ' image03', ' image04']
I agree, this is a dirty hack, but does the JOB, without much effort.
Solution 5:
This is a generic recursive flatten which can be used to work with any combination of types which should or should not be flattened:
import collections
defgeneric_flatten(seq, flatten_types=(tuple,list,set),atom_types=(basestring,dict),fixtype=True):
newseq = []
for item in seq:
if (notisinstance(collections.Iterable)) orany(isinstance(i,t) for t in atom_types):
newseq.append(item)
elifany(isinstance(i,t) for t in flatten_types): # set flatten_types to (object,) or (collections.Iterable,) to disable check
newseq.extend(generic_flatten(item, flatten_types, atom_types,fixtype)
if fixtype andtype(newseq) isnottype(seq):
newseq = type(seq)(newseq)
return newseq
yield
and chain
could be used to create a generic iterator-based version.
Post a Comment for "Flatten A List Of Strings And Lists Of Strings And Lists In Python"