Supposing I have a multiple nested list of following structure:
['p', [['p', 'q'], [['~p', '~r'], [['r', '~s'], ['s', '~q']]]]]
where every second element of nested list is another nested list (except for innermost list), I want to output to extract all list with the strings such that my output appears as follows:
['p', ['p', 'q'], ['~p', '~r'], ['r', '~s'], ['s', '~q']]
I have implemented the following code:
def flatten_nested_list(nested_list):
flat_list = []
for item in nested_list:
if isinstance(item, list) and isinstance(item[1], list):
flat_list.append(item[0])
flat_list.extend(flatten_nested_list(item[1]))
else:
flat_list.append(item)
return flat_list
nested_list = ['p', [['~p', 'q'], [['~p', '~r'], [['r', '~s'], ['s', '~q']]]]]
flat_result = flatten_nested_list(nested_list)
print(flat_result)
However my function does not handle the innermost list properly and my output is as follows:
['p', ['~p', 'q'], ['~p', '~r'], ['r', '~s'], 's', '~q']
Can any change be suggested so that the innermost list be handled properly ?
>Solution :
IIUC, you can use recursion:
lst = ["p", [["p", "q"], [["~p", "~r"], [["r", "~s"], ["s", "~q"]]]]]
def flatten(lst):
if isinstance(lst[-1], list):
yield lst[0]
yield from flatten(lst[-1])
else:
yield lst
print(list(flatten(lst)))
Prints:
['p', ['p', 'q'], ['~p', '~r'], ['r', '~s'], ['s', '~q']]
EDIT:
lst = ["p", [["~p", "q"], [["~q", "r"], "~r"]]]
def flatten(lst):
match [lst[0], lst[1]]:
case str(), list():
yield lst[0]
yield from flatten(lst[1])
case list(), list():
yield from flatten(lst[0])
yield from flatten(lst[1])
case list(), str():
yield from flatten(lst[0])
yield lst[1]
case _:
yield lst
print(list(flatten(lst)))
Prints:
['p', ['~p', 'q'], ['~q', 'r'], '~r']