Reputation: 597
Please see the simplified example:
A = [(721,'a'),(765,'a'),(421,'a'),(422,'a'),(106,'b'),(784,'a'),(201,'a'),(206,'b'),(207,'b')]
I want group adjacent tuples with attribute 'a', every two pair wise and leave tuples with 'b' alone.
So the desired tuple would looks like:
A = [[(721,'a'),(765,'a')],
[(421,'a'),(422,'a')],
[(106,'b')],
[(784,'a'),(201,'a')],
[(206,'b')],
[(207,'b')]]
What I can do is to build two separated lists contains tuples with a
and b
.
Then pair tuples in a
, and add back. But it seems not very efficient. Any faster and simple solutions?
Upvotes: 3
Views: 1077
Reputation: 4629
No need to use two lists. Edit: If the 'a' are not assumed to come always as pairs/adjacent
A = [(721,'a'),(765,'a'),(421,'a'),(422,'a'),(106,'b'),(784,'a'),(201,'a'),(206,'b'),(207,'b')]
new_list = []
i = 0
while i < len(A):
if i == len(A)-1:
new_list.append([A[i]])
i+=1
elif (A[i][1]==A[i+1][1]=='a') :
new_list.append([A[i], A[i+1]])
i += 2
else:
new_list.append([A[i]])
i += 1
print(new_list)
Upvotes: 0
Reputation: 71451
You can use itertools.groupby
:
import itertools
A=[(721,'a'),(765,'a'),(421,'a'),(422,'a'),(106,'b'),(784,'a'),(201,'a'),(206,'b'),(207,'b')]
def split(s):
return [s[i:i+2] for i in range(0, len(s), 2)]
new_data = [i if isinstance(i, list) else [i] for i in list(itertools.chain(*[split(list(b)) if a == 'a' else list(b) for a, b in itertools.groupby(A, key=lambda x:x[-1])]))
Output:
[[(721, 'a'), (765, 'a')], [(421, 'a'), (422, 'a')], [(106, 'b')], [(784, 'a'), (201, 'a')], [(206, 'b')], [(207, 'b')]]
Upvotes: 2
Reputation: 11060
Assuming a
items are always in pairs, a simple approach would be as follows.
Look at the first item - if it's an a
, use it and the next item as a pair. Otherwise, just use the single item. Then 'jump' forward by 1 or 2, as appropriate:
A=[(721,'a'),(765,'a'),(421,'a'),(422,'a'),(106,'b'),(784,'a'),(201,'a'),(206,'b'),(207,'b')]
result = []
count = 0
while count <= len(A)-1:
if A[count][1] == 'a':
result.append([A[count], A[count+1]])
count += 2
else:
result.append([A[count]])
count += 1
print(result)
Upvotes: 2