Reputation: 41
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
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
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
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
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
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