sal
sal

Reputation: 74

Split list into nested list

I have a nested list that I am trying to split into smaller lists nested inside the original. I am splitting the lists by a specific element. I've figured that part out, but when I try to iterate through the original list, but only get the last list returned.

animals  = [["animal", "cat", "dog", "bird", "animal", "cat", "snake", "bird"], 
     ["animal", "cat", "iguana", "bird", "animal", "lizard", "dog", "bird"]]

for n in animals:
    it  = iter(n)
    combined = [[next(it)]]
    for ele in it:
        if ele != "animal":
            combined[-1].append(ele)
        else:
            combined.append([ele])
    
print combined

Output:

[['animal', 'cat', 'iguana', 'bird'], ['animal', 'lizard', 'dog', 'bird']]

Desired output:

[["animal", "cat", "dog", "bird"], ["animal", "cat", "snake", "bird"], ['animal', 'cat', 'iguana', 'bird'], ['animal', 'lizard', 'dog', 'bird']]

Upvotes: 1

Views: 302

Answers (4)

Timus
Timus

Reputation: 11371

Since the structure of animals could be irregular this might be a solution:

from itertools import groupby

combined = [
    ['animal'] + list(group)
    for sublist in animals
    for key, group in groupby(sublist, key=lambda s: s == 'animal') if not key
]

Output:

[['animal', 'cat', 'dog', 'bird'],
 ['animal', 'cat', 'snake', 'bird'],
 ['animal', 'cat', 'iguana', 'bird'],
 ['animal', 'lizard', 'dog', 'bird']]

Upvotes: 0

Paul M.
Paul M.

Reputation: 10819

You can chain the elements of the original sub-lists together, and then grab four-element chunks at a time to create new sub-lists:

from itertools import islice, chain

animals = [
    ["animal", "cat", "dog", "bird", "animal", "cat", "snake", "bird"],
    ["animal", "cat", "iguana", "bird", "animal", "lizard", "dog", "bird"]
]

chained = chain.from_iterable(animals)

print([list(islice(chained, 4)) for _ in range(4)])

Output:

[['animal', 'cat', 'dog', 'bird'], ['animal', 'cat', 'snake', 'bird'], ['animal', 'cat', 'iguana', 'bird'], ['animal', 'lizard', 'dog', 'bird']]
>>> 

However, you're hardcoding the range(4) in this case, which is not ideal. Instead of the list-comprehension, maybe something like the following would be more desirable:

output = []
while sublist := list(islice(chained, 4)):
    output.append(sublist)

print(output)

Upvotes: 0

Walid
Walid

Reputation: 728

Try this pythonic solution:

str_ = ' '.join([a for animal in animals for a in animal])
list_of_animals = [['animal']+st.split() for st in str_.split("animal") if len(st)>1]

It gives the desired output.

Upvotes: 2

Lydia van Dyke
Lydia van Dyke

Reputation: 2526

animals  = [["animal", "cat", "dog", "bird", "animal", "cat", "snake", "bird"], ["animal", "cat", "iguana", "bird", "animal", "lizard", "dog", "bird"]]

result = []
for row in animals:
    result_row = []
    for element in row:
        if element == "animal":
            if result_row:
                result.append(result_row)
            result_row = []
        result_row.append(element)
    result.append(result_row)
print(result)

Upvotes: 0

Related Questions