John
John

Reputation: 123

zip function is returning duplicates

Currently my list is:

[[(881, 886), ('Twilight Sparkle', 'Rainbow Dash')],
 [(883, 885), ('Applejack', 'Rarity')], 

[(887, 884), ('Princess Celestia', 'Pinkie Pie')],

 [(888, 882), ('Princess Luna', 'Fluttershy')]]

I want it instead to have the format:

   [(pid1, pname1, pid2, pname2),

 (pid3, pname3, pid4, pname4), 

(pid5, pname5, pid6, pname6), 

(pid7, pname7, pid8, pname8)] 

So that it is player1, name 1, player2, name 2

Is it better to do it that in the previous zip function and zip it a different way or manipulate the list now.

I thought to do it

temp = x[1]
x[1] = x[2]
x[2] = x[3]

But I'm not sure how to do it.

This is the zip function:

for i in range(0,length, 2):
    pairs =zip(list[i],list[i+1])

Prior to zipping it was in this format:

[(881, 'Twilight Sparkle'), (886, 'Rainbow Dash'),
 (883, 'Applejack'), (885, 'Rarity'), 
(887, 'Princess Celestia'), (884, 'Pinkie Pie'),
 (888, 'Princess Luna'), (882, 'Fluttershy')]

Is there a way to change the zip function so that it puts the first two in a list, then the second two, and so on but maintains the order of id, name, id, name rather than combining the id and name?

And I want it to be in the format:

[(881, 'Twilight Sparkle',886, 'Rainbow Dash'),
 (883, 'Applejack',885, 'Rarity'), 
(887, 'Princess Celestia', 884, 'Pinkie Pie'),
 (888, 'Princess Luna', 882, 'Fluttershy')]

Upvotes: 1

Views: 153

Answers (4)

Moinuddin Quadri
Moinuddin Quadri

Reputation: 48067

You may use zip() with itertools.chain() along with list comprehension as:

from itertools import chain

[tuple(chain(*zip(*item))) for item in my_list]

which returns:

[(881, 'Twilight Sparkle', 886, 'Rainbow Dash'), 
(883, 'Applejack', 885, 'Rarity'), 
(887, 'Princess Celestia', 884, 'Pinkie Pie'), 
(888, 'Princess Luna', 882, 'Fluttershy')]

where my_list is the initial list mentioned in the question

Upvotes: 3

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160407

You could also do it with a nice little comprehension:

>>> r = [sum(zip(*sub), ()) for sub in l]

Where you unpack the contents in zip with zip(*sub) and then flatten the nested tuple created with sum(iterable, ()).

This yields:

>>> print(r)
[(881, 'Twilight Sparkle', 886, 'Rainbow Dash'),
 (883, 'Applejack', 885, 'Rarity'),
 (887, 'Princess Celestia', 884, 'Pinkie Pie'),
 (888, 'Princess Luna', 882, 'Fluttershy')]

Upvotes: 1

BrechtDeMan
BrechtDeMan

Reputation: 6912

List comprehensions would probably be a better approach here:

[(item[0][0], item[1][0], item[0][1], item[1][1]) for item in l]

So for your example

players = [[(881, 886), ('Twilight Sparkle', 'Rainbow Dash')],
           [(883, 885), ('Applejack', 'Rarity')], 
           [(887, 884), ('Princess Celestia', 'Pinkie Pie')],
           [(888, 882), ('Princess Luna', 'Fluttershy')]]

you would get

players_reformatted = [(item[0][0], item[1][0], item[0][1], item[1][1]) for item in players]

which gives

[(881, 'Twilight Sparkle', 886, 'Rainbow Dash'), 
 (883, 'Applejack', 885, 'Rarity'), 
 (887, 'Princess Celestia', 884, 'Pinkie Pie'), 
 (888, 'Princess Luna', 882, 'Fluttershy')]

Upvotes: 1

Alex Hall
Alex Hall

Reputation: 36033

Looks like you don't want to zip at all, you just want to concatenate pairs of tuples:

players = [(881, 'Twilight Sparkle'), (886, 'Rainbow Dash'),
           (883, 'Applejack'), (885, 'Rarity'),
           (887, 'Princess Celestia'), (884, 'Pinkie Pie'),
           (888, 'Princess Luna'), (882, 'Fluttershy')]
pairs = [players[i] + players[i + 1] for i in range(0, len(players), 2)]
for pair in pairs:
    print(pair)

Output:

(881, 'Twilight Sparkle', 886, 'Rainbow Dash')
(883, 'Applejack', 885, 'Rarity')
(887, 'Princess Celestia', 884, 'Pinkie Pie')
(888, 'Princess Luna', 882, 'Fluttershy')

Upvotes: 1

Related Questions