Python
Lists
Data Structures
Programming
Algorithms

Replace list of list with condensed list of list while maintaining order

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When people want to "condense" a list of lists while maintaining order, the real question is what kind of condensation they mean. The most common interpretation is to remove repeated values while keeping the first-seen order, either within each sublist or across the whole nested structure. In Python, that is straightforward once the rule is made explicit.

Condensing Values While Preserving First Appearance

Suppose you have nested lists with repeated values:

python
1data = [
2    ["a", "b", "a"],
3    ["b", "c"],
4    ["c", "d", "a"],
5]

If the goal is to produce a condensed nested result where each value appears only once overall, in the order it is first seen, iterate left to right and keep a seen set.

python
1from typing import Iterable
2
3
4def condense_nested_lists(rows: Iterable[list[str]]) -> list[list[str]]:
5    seen = set()
6    condensed = []
7
8    for row in rows:
9        new_row = []
10        for item in row:
11            if item not in seen:
12                seen.add(item)
13                new_row.append(item)
14        if new_row:
15            condensed.append(new_row)
16
17    return condensed
18
19
20data = [
21    ["a", "b", "a"],
22    ["b", "c"],
23    ["c", "d", "a"],
24]
25
26print(condense_nested_lists(data))

Output:

python
[['a', 'b'], ['c'], ['d']]

This keeps the original encounter order across the whole structure and removes repeated values cleanly.

Condensing Only Within Each Sublist

Sometimes the intent is narrower: remove duplicates inside each sublist but keep repeats across different rows.

python
1
2def dedupe_each_row(rows):
3    result = []
4    for row in rows:
5        result.append(list(dict.fromkeys(row)))
6    return result
7
8
9data = [[1, 2, 1, 3], [2, 2, 4], [3, 1, 1]]
10print(dedupe_each_row(data))

Output:

python
[[1, 2, 3], [2, 4], [3, 1]]

dict.fromkeys is useful here because dictionaries preserve insertion order in modern Python.

Flattening Then Regrouping

A more aggressive version of condensation is to flatten all values, remove duplicates globally, and then put the result into one list.

python
1
2def flatten_unique(rows):
3    flat = []
4    seen = set()
5
6    for row in rows:
7        for item in row:
8            if item not in seen:
9                seen.add(item)
10                flat.append(item)
11
12    return [flat]
13
14
15data = [[1, 2], [2, 3], [1, 4]]
16print(flatten_unique(data))

Output:

python
[[1, 2, 3, 4]]

This is appropriate when the outer grouping is no longer important and you only care about ordered unique values.

Why Order Preservation Needs Extra Care

A plain set removes duplicates, but it does not preserve the original first-seen sequence in a way you should rely on for ordered output. That is why most correct solutions combine:

  • a seen set for fast membership checks
  • a list for the final ordered result

This gives both good performance and predictable ordering.

For large data, the pattern stays efficient because each membership test is constant time on average.

Designing the Right Condensation Rule

Before coding, decide which of these you actually need:

  • dedupe within each row only
  • dedupe across all rows while preserving first appearance
  • flatten everything into one condensed row

The title of the problem often sounds like one thing, but the required output may reflect another. The algorithm is only correct once the condensation rule is fixed.

Example With Numbers and Stable Grouping

Here is a version that preserves the outer structure but removes items already emitted in earlier rows.

python
1
2def stable_condense(rows):
3    seen = set()
4    output = []
5
6    for row in rows:
7        kept = [item for item in row if item not in seen and not seen.add(item)]
8        if kept:
9            output.append(kept)
10
11    return output
12
13
14rows = [[1, 2, 2], [2, 3], [3, 4, 1], [5]]
15print(stable_condense(rows))

Output:

python
[[1, 2], [3], [4], [5]]

The seen.add(item) trick works because set.add returns None, which is falsey. It is compact, but some teams prefer the more explicit loop version for readability.

Common Pitfalls

A common mistake is using a plain set as the final result and then discovering the original order is lost.

Another issue is not defining whether duplicates should be removed within each sublist, across the whole nested structure, or both. Different interpretations produce different correct outputs.

Developers also sometimes flatten everything unintentionally when they still needed to keep the outer list structure.

Finally, clever list comprehensions can make the code harder to read than a simple loop. When order rules matter, explicit loops are often the safer choice.

Summary

  • First define what "condensed" should mean for your nested list.
  • Use a seen set plus ordered output list when preserving first appearance matters.
  • 'dict.fromkeys is a clean option for deduping within one sublist.'
  • Do not rely on a raw set for ordered output.
  • Prefer the simplest algorithm that matches the exact output shape you need.

Course illustration
Course illustration