How to group items in list in python if the value change?
Question:
Suppose I have a list
msg_type =["sent-message", "received-message", "received-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "sent-message", "received-message" ]
How would I be able to group this if there is change in next item
for ex: first set would be :
("sent-message", "received-message", "received-message")
second set would be:
("sent-message", "received-message")
and if sent-message
repeats itself it should be in one group
"sent-message", "sent-message", "received-message"
I am able to achieve it for all other cases except the last one.
Basically I want to group them by single exchange
expected result:
conversations = [(0,2), (3,4),(5,7),(8,10), (11,13), (14,16),(17,19),(20,22),(23,24),(25,26)]
Answers:
Here’s a hacky solution. It returns the expected results, however I haven’t fully tested every use case. Hope this helps
def group_conversations(messages):
conversations = []
start = 0
for k, v in enumerate(messages[1:]):
if v == "sent-message": # Switched
if messages[k] == "sent-message": # Sent 2 in a row, skip
continue
conversations += [[start, k]]
start = k+1
last_group = [[conversations[-1][1]+1, len(messages)-1]] # Hack to grab the last conv which is excluded
return conversations + last_group
You can try:
from itertools import groupby
out = []
for k, g in groupby(enumerate(msg_type), lambda k: k[1]):
g = list(g)
if k == "sent-message":
out.append([g[0][0]])
else:
out[-1].append(g[-1][0])
print(out)
Prints:
[[0, 2], [3, 4], [5, 7], [8, 10], [11, 13], [14, 16], [17, 19], [20, 22], [23, 24], [25, 26]]
Suppose I have a list
msg_type =["sent-message", "received-message", "received-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "sent-message", "received-message" ]
How would I be able to group this if there is change in next item
for ex: first set would be :
("sent-message", "received-message", "received-message")
second set would be:
("sent-message", "received-message")
and if sent-message
repeats itself it should be in one group
"sent-message", "sent-message", "received-message"
I am able to achieve it for all other cases except the last one.
Basically I want to group them by single exchange
expected result:
conversations = [(0,2), (3,4),(5,7),(8,10), (11,13), (14,16),(17,19),(20,22),(23,24),(25,26)]
Here’s a hacky solution. It returns the expected results, however I haven’t fully tested every use case. Hope this helps
def group_conversations(messages):
conversations = []
start = 0
for k, v in enumerate(messages[1:]):
if v == "sent-message": # Switched
if messages[k] == "sent-message": # Sent 2 in a row, skip
continue
conversations += [[start, k]]
start = k+1
last_group = [[conversations[-1][1]+1, len(messages)-1]] # Hack to grab the last conv which is excluded
return conversations + last_group
You can try:
from itertools import groupby
out = []
for k, g in groupby(enumerate(msg_type), lambda k: k[1]):
g = list(g)
if k == "sent-message":
out.append([g[0][0]])
else:
out[-1].append(g[-1][0])
print(out)
Prints:
[[0, 2], [3, 4], [5, 7], [8, 10], [11, 13], [14, 16], [17, 19], [20, 22], [23, 24], [25, 26]]