Bourbon
Bourbon

Reputation: 41

How to split list into nested lists with the same first value?

I have python list (example):

mylist = ["AA - AA", "qwerty", "123456789", "nvidia", "fan", "8765", "AA - AA", "group", "bread", "plate", "knife", "AA - AA", "123123123", "laptop", "666"]

(My real list contains for about 2000 elements, what you see above is just a short example.)

I need to split that list into:

newlist = [["AA - AA", "qwerty", "123456789", "nvidia", "fan", "8765"], ["AA - AA", "group", "bread", "plate", "knife"], ["AA - AA", "123123123", "laptop", "666"]]

As you can see, each nested list has a different number of elements and the same first element "AA - AA".

How can I split a list into nested lists, so that it has the first element "AA - AA" and the last element (the element before the next "AA - AA")?

Upvotes: 0

Views: 656

Answers (5)

Adon Bilivit
Adon Bilivit

Reputation: 27018

Assuming the first element in mylist is 'AA - AA' then:

mylist = ["AA - AA", "qwerty", "123456789", "nvidia", "fan", "8765", "AA - AA", "group", "bread", "plate", "knife", "AA - AA", "123123123", "laptop", "666"]

result = []

for e in mylist:
    if e == 'AA - AA':
        result.append([e])
    else:
        result[-1].append(e)

print(result)

Output:

[['AA - AA', 'qwerty', '123456789', 'nvidia', 'fan', '8765'], ['AA - AA', 'group', 'bread', 'plate', 'knife'], ['AA - AA', '123123123', 'laptop', '666']]

Note:

There's certainly no need for itertools, numpy or temporary/intermediate variables for something so trivial

Upvotes: 1

René
René

Reputation: 4827

mylist = ["AA - AA", "qwerty", "123456789", "nvidia", "fan", "8765", "AA - AA", "group", "bread", "plate", "knife", "AA - AA", "123123123", "laptop", "666"]

ranges = [i for i, j in enumerate(mylist) if j == 'AA - AA'] + [len(mylist)]
output = [[mylist[ranges[x]:ranges[x+1]]] for x in range(len(ranges)-1)]

Output:

[[['AA - AA', 'qwerty', '123456789', 'nvidia', 'fan', '8765']], [['AA - AA', 'group', 'bread', 'plate', 'knife']], [['AA - AA', '123123123', 'laptop', '666']]]

Upvotes: 0

Jacob
Jacob

Reputation: 304

I would like to present a third one-line solution:

[mylist[idx:idx1] for idx, idx1 in zip([i for i,item in enumerate(mylist) if item=='AA - AA'][:-1],[i for i,item in enumerate(mylist) if item=='AA - AA'][1:])]

Explanation:

[i for i,item in enumerate(mylist) if item=='AA - AA']

returns all the index positions of your 'AA - AA' key. Since we want to extract the values of mylist between to adjacent occurences of the key I have created one list that is shifted by one using the [1:] Thus, no Index ot of range errors. Maybe there is a more elegant solution for this problem

The last step is to iterate over both lists in parallel and building the list.

Upvotes: 0

core_not_dumped
core_not_dumped

Reputation: 877

Try:

import numpy as np

mylist, lst = ["AA - AA", "qwerty", "123456789", "nvidia", "fan", "8765", "AA - AA", "group", "bread", "plate", "knife", "AA - AA", "123123123", "laptop", "666"], []
where = np.where(np.array(mylist + ["AA - AA"]) == "AA - AA")[0]
for i in range(len(where)-1):   lst.append(mylist[where[i]:where[i+1]-1])
print(lst)

Result:

[['AA - AA', 'qwerty', '123456789', 'nvidia', 'fan'],
 ['AA - AA', 'group', 'bread', 'plate'],
 ['AA - AA', '123123123', 'laptop']]

Upvotes: 0

Chang Ye
Chang Ye

Reputation: 1215

python has build in method, groupby for this.

mylist = ["AA - AA", "qwerty", "123456789", "nvidia", "fan", "8765", "AA - AA", "group", "bread", "plate", "knife", "AA - AA", "123123123", "laptop", "666"]

from itertools import groupby
x = (list(g) for _, g in groupby(mylist, key='AA - AA'.__eq__))
[i+j for i, j in zip(x, x)]

# OUPUT is:
# [['AA - AA', 'qwerty', '123456789', 'nvidia', 'fan', '8765'], ['AA - AA', 'group', 'bread', 'plate', 'knife'], ['AA - AA', '123123123', 'laptop', '666']]

Upvotes: 1

Related Questions