How can I flatten lists without splitting strings?
Solution:
def flatten(foo):
for x in foo:
if hasattr(x, '__iter__') and not isinstance(x, str):
for y in flatten(x):
yield y
else:
yield x
Old version for Python 2.x:
def flatten(foo):
for x in foo:
if hasattr(x, '__iter__'):
for y in flatten(x):
yield y
else:
yield x
(In Python 2.x, strings conveniently didn't actually have an __iter__
attribute, unlike pretty much every other iterable object in Python. Note however that they do in Python 3, so the above code will only work in Python 2.x.)
Flatten a list of strings and lists of strings and lists in Python
The oft-repeated flatten
function can be applied to this circumstance with a simple modification.
from collections import Iterable
def flatten(coll):
for i in coll:
if isinstance(i, Iterable) and not isinstance(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.)
Split and flatten a list of strings
try:
res = []
for i in lst:
res.extend(i.split(","))
Another option is to use reduce
:
res = list(reduce(lambda a, b: a + b.split(','), lst, []))
Flattening a nested list in Python
arr = [['31', '1'], '32', ['8', '16'], ['1', '3', '12'], ['4', '12'], '32', ['1', '3', '12'], ['4', '12'], '32', ['30', '1', '1']]
def extract(array):
for item in array:
if type(item) in [set, list, tuple]:
yield from extract(item)
continue
yield item
print(list(extract(arr))) # ['31', '1', '32', '8', '16', '1', '3', '12', '4', '12', '32', '1', '3', '12', '4', '12', '32', '30', '1', '1']
Flatten list of list of strings
If you have a list of strings of Python expressions that represent lists (how's that for a nested clause), you will have to use ast.literal_eval()
to get back to reality, as it were.
>>> import ast
>>> list1 = ["['word']", "['second', 'first']", "['first']"]
>>> list2 = [ast.literal_eval(item) for item in list1]
[['word'], ['second', 'first'], ['first']]
Using ast.literal_eval()
, as opposed to the dangerous eval()
that you shouldn't use is safe, as it only evaluates literals that can have no side effects.
How to split strings inside a list by given delimiter and flatten the sub-strings lists
It would probably be easier to make a new list:
blocks = [
"item-1",
"item-2",
"item-3.0;item-3.1;item-3.2"
]
new_blocks = []
for block in blocks:
for c in block.split(";"):
new_blocks.append(c)
# new_blocks = ['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']
Flatten a list and a string
You can use reduce
with a lambda
function
l = lambda x,y: (x if isinstance(x,list) else [x]) + (y if isinstance(y,list) else [y])
reduce(l, my_list)
Example
>>> my_list = [['abc'],[1,2,3]]
>>> reduce(l, my_list)
['abc', 1, 2, 3]
>>> my_list = ['abs',[1,2,3]]
>>> reduce(l, my_list)
['abs', 1, 2, 3]
That way, you literally reduce a list of separte things to one list of these things.
It works with as many lists inside lists you want.
For instance:
>>> my_list = ['abs',[1,2,[3,4]]]
>>> tmp = reduce(l, my_list)
#tmp = ['abs', 1, 2, [3,4]] - Just run again
>>> reduce(l, tmp)
>>> ['abs', 1, 2, 3, 4]
It should be noticed that this is not an efficient method, as highlighted by Two-bit Alchemist
Related Topics
What Is the Fastest Way to Open Urls in New Tabs via Selenium - Python
Making Heatmap from Pandas Dataframe
Using Moviepy, Scipy and Numpy in Amazon Lambda
Conditionally Fill Column Values Based on Another Columns Value in Pandas
Reducing Size of Pyinstaller Exe
Check If a File Is Open in Python
Change the Colors Within Certain Range to Another Color Using Opencv
Is There Any Simple Way to Benchmark Python Script
Convert Image from Pil to Opencv Format
Sort Tuples Based on Second Parameter
When Are Objects Garbage Collected in Python
Is There Any Difference Between "Foo Is None" and "Foo == None"
How to Insert Pandas Dataframe via MySQLdb into Database
How to Handle a Broken Pipe (Sigpipe) in Python
Split a List into Parts Based on a Set of Indexes in Python
Parameter Substitution for a SQLite "In" Clause