user1691477
user1691477

Reputation: 5

Unzip vs explicit loop

what's the difference between the two ways to unzip two zipped lists?

assert isinstance(X, list)
assert isinstance(X[0], tuple)
assert isinstance(X[0][0], list)
assert isinstance(X[0][0][0], dict)

X_model = []
X_synth = []
for row in X:
    X_model.append(row[0])
    X_synth.append(row[1])

X_model is now a list of list of dict

X_model, X_synth, = zip(*X)

X_model is a tuple of list of dicts shouldn't the results be the same?

Upvotes: 0

Views: 65

Answers (2)

AChampion
AChampion

Reputation: 30258

The equivalent to zip() would be:

X_model = tuple(x for x, _ in X)
X_synth = tuple(x for _, x in X)

But this isn't very efficient as it cycles X twice. Note: tuples are immutable, so you can't efficiently do it in a loop as you would be creating a new tuple each time.

Upvotes: 0

Moyamo
Moyamo

Reputation: 368

Let's use an example. For simplicity sake, instead of using a list of dicts let's use numbers. Notice the first element of every tuple is odd and the second element of every tuple is even.

>>> X = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
>>> X_model = []
>>> X_synth = []
>>> for row in X:
...     X_model.append(row[0])
...     X_synth.append(row[1])
...
>>> X_model
[1, 3, 5, 7, 9]
>>> X_synth
[2, 4, 6, 8, 10]
>>> X_model, X_synth = zip(*X)
>>> X_model
(1, 3, 5, 7, 9)
>>> X_synth
(2, 4, 6, 8, 10)

Let's consider zip(*X). zip(*X) is equivalent to

zip((1, 2), (3, 4), (5, 6), (7, 8), (9, 10))

From the Python Docs

zip: This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.

Hence zip will return a list of tuples where the 0th tuple contains the 0th element from each argument (all odd numbers) and the 1st tuple contains all the 1st element from each argument (all even numbers)

X_model, X_synth = [(1, 3, 5, 7, 9), (2, 4, 6, 8, 10)]

Upvotes: 1

Related Questions