Reputation: 157
I'm currently working with itertools
to create and return a list whose elements are lists that contain the consecutive runs of equal elements of the original list.
import itertools
it = [1, 1, 5, 5, 5, 'test', 'test', 5]
new = len(it)
for a in range(new):
return [list(k) for a, k in itertools.groupby(it)]
For the above example the result is:
[[1, 1], [5, 5, 5], ['test', 'test'], [5]]
Can I achieve this without using itertools
?
Upvotes: 4
Views: 5319
Reputation: 21
You could have a look at the function in itertools to see how they are doing it.
Here is one way which shows the logic clearly (can be further reduced):
def i_am_itertool():
it = [1, 1, 5, 5, 5, 'test', 'test', 5]
ret = []
temp = []
last = it[0]
for e in it:
if e == last:
temp.append(e)
else:
ret.append(temp) # Add previous group
temp = [e] # Start next group
last = e
ret.append(temp) # Add final group
return ret
print(i_am_itertool())
Output:
[[1, 1], [5, 5, 5], ['test', 'test'], [5]]
Upvotes: 1
Reputation: 5011
To be honest a simple for loop could make this work, you don't even have to import itertools
.
The simplest way to do this is by using this:
it = [1, 1, 5, 5, 5, 'test', 'test', 5]
result = []
for (i, x) in enumerate(it):
if i < 1 or type(x) != type(it[i - 1]) or x != it[i - 1]:
result.append([x])
else:
result[-1].append(x)
print(result)
Or, in function form:
def type_chunk(it):
result = []
for (i, x) in enumerate(it):
if i < 1 or type(x) != type(it[i - 1]) or x != it[i - 1]:
result.append([x])
else:
result[-1].append(x)
return result
You would then use the function like this:
print(type_chunk([1, 1, 5, 5, 5, 'test', 'test', 5]))
You could even skip the type checking and only look for equal values:
def type_chunk(it):
result = []
for (i, x) in enumerate(it):
if i < 1 or x != it[i - 1]:
result.append([x])
else:
result[-1].append(x)
return result
Good luck.
Upvotes: 1
Reputation: 106553
You can pair adjacent items by zipping the list with itself but with a padding of float('nan')
since it can't be equal to any object, and then iterate through the zipped pairs to append items to last sub-list of the output list, and add a new sub-list when the adjacent items are different:
output = []
for a, b in zip([float('nan')] + it, it):
if a != b:
output.append([])
output[-1].append(b)
output
becomes:
[[1, 1], [5, 5, 5], ['test', 'test'], [5]]
Upvotes: 1