achimneyswallow achimneyswallow - 4 months ago 10
Python Question

Zip through a list and get every pair of items

I would like to zip through a list of strings as below

collections = [u'Room Designers', u'BCRF', u'House']


What I would like to achieve is 6 combinations of the three elements in the list -

("Room Designers", "BCRF"), ("Room Designers", "House"), ("BCRF", "House"), ("BCRF", "Room Designers"), ("House", "BCRF"), ("House", "Room")


With my code below

zipall = [zip(i,j) for i in collections for j in collections if i!=j]


I obtained:

[[(u'R', u'B'), (u'o', u'C'), (u'o', u'R'), (u'm', u'F')], [(u'R', u'H'), (u'o', u'o'), (u'o', u'u'), (u'm', u's'), (u' ', u'e')], [(u'B', u'R'), (u'C', u'o'), (u'R', u'o'), (u'F', u'm')], [(u'B', u'H'), (u'C', u'o'), (u'R', u'u'), (u'F', u's')], [(u'H', u'R'), (u'o', u'o'), (u'u', u'o'), (u's', u'm'), (u'e', u' ')], [(u'H', u'B'), (u'o', u'C'), (u'u', u'R'), (u's', u'F')]]


What would be a better way to do this? Thank you!!

Answer

If you wanted to do it the way you've written, you need to omit the final zip call because that will break the strings up into their individual characters and pair those up.

zipall = [(i,j) for i in collections for j in collections if i!=j]

# [(u'Room Designers', u'BCRF'), (u'Room Designers', u'House'), (u'BCRF', u'Room Designers'), (u'BCRF', u'House'), (u'House', u'Room Designers'), (u'House', u'BCRF')]

For these sorts of problems though, the itertools library is very handy. For this specific problem, you can use itertools.permutations to yield all permutations of 2 elements. With permutations (as opposed to combinations), the order of the pairing matters.

import itertools

# Create all permutations of 2 items
output = list(itertools.permutations(collections, 2))

# [(u'Room Designers', u'BCRF'), (u'Room Designers', u'House'), (u'BCRF', u'Room Designers'), (u'BCRF', u'House'), (u'House', u'Room Designers'), (u'House', u'BCRF')]