You can avoid assemble, disassemble, tag_datum if you leverage on key param of both itertools.groupby and sorted and condense them into one simple function.
Build a custom function for key param
Write a function to return the length of each value in the dictionary.
val_len = lambda x: len(x['ids'])
Now pass this as argument for key in both itertools.groupby and sorted
from itertools import groupby
def transform(data):
sorted_data = sorted(data, key=val_len)
return [list(group) for _, group in groupby(sorted_data, key=val_len)]
transform(data) # data taken from question itself.
# [[{'ids': [1]}, {'ids': [4]}, {'ids': [3]}, {'ids': [2]}],
# [{'ids': [3, 4]}, {'ids': [1, 2]}]]
Details
sorted_data = sorted(data, key=val_len) # sorts data based the length of
# the value of 'ids'
# [{'ids': [1]}, ---|
# {'ids': [4]}, |-- group with length 1
# {'ids': [3]}, |
# {'ids': [2]}, ---|
# {'ids': [3, 4]},---|-- group with length 2
# {'ids': [1, 2]}]---|
groupby(sorted_data, key=val_len) # groups data based on the length of
# the value of 'ids'