Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Collections (Retired) Tuples Combo

More elegant way to solve this Python Code Challenge?

In this Code Challenge, the task was

Create a function named combo() that takes two iterables and returns a list of tuples. Each tuple should hold the first item in each list, then the second set, then the third, and so on. Assume the iterables will be the same length.

Here's my code ...

def combo(iterable_1, iterable_2):
  list_of_tuples = []
  count = 0
  for item in iterable_1:
    list_of_tuples.append((iterable_1[count], iterable_2[count]))
    count += 1
  return list_of_tuples

I'm pretty sure I should've used enumerate but I wasn't sure how to do it.

Code reviews welcome!

11 Answers

Hi Ryan,

If you've been introduced to range() then you could use that to get rid of your count variable:

def combo(iterable_1, iterable_2):
  list_of_tuples = []
  for index in range(len(iterable_1)):
    list_of_tuples.append((iterable_1[index], iterable_2[index]))

  return list_of_tuples

I'm not sure if this is the intended way to use enumerate() but this is what I came up with using that. It doesn't look that much different from using range() so perhaps I'm not using it properly.

def combo(iterable_1, iterable_2):
  list_of_tuples = []
  for index, item2 in enumerate(iterable_2):
    list_of_tuples.append( (iterable_1[index], item2) )

  return list_of_tuples

There is the zip() function which I don't know if that's considered cheating here because it contains all the functionality needed and makes it a one liner.

def combo(iterable_1, iterable_2):
  return list(zip(iterable_1, iterable_2))

Kenneth Love , was the file name "zippy.py" a hint to do research and find the zip function?

The code comments seem to imply there's a solution not using .append()

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

All of Python is valid so zip() isn't cheating. The plan, obviously though, is for you to make your own version of zip() instead of just using it.

The only way to do it without list.append() that we've covered would be to concatenate an ad hoc list with your existing list. Or, I suppose, you could get really weird and just change iterable_1 or iterable_2 in place but you really shouldn't do that.

Hi Kenneth,

Thanks for the follow up. I probably should have clarified what I meant by cheating. Maybe "taking a shortcut" would have been a better phrase. I thought the goal was to solve the problem as a series of steps and not to use a function that does all the work for you and you have confirmed that.

Any comment on the enumerate() solution? I know it passes the challenge but is there a better way to code that solution?

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Jason Anello Nope, that's pretty much how I pictured people using it. Well, that or enumerate(iterable_1), but that's effectively the exact same idea.

Oh, I guess you could have been really crazy and combined both lists, then grabbed a current index and the current index + the length of the first iterable.

Michel Moreau L
Michel Moreau L
21,751 Points

Hi! Nice answer, I had the same one :). I've read about using xrange instead of range in some occasions. Could you comment on the use of xrange and in which circumstances we should use it?

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Michel Moreau L You don't ever need to use xrange in Python 3 (in fact, it doesn't exist). Python 2's xrange is Python 3's range.

Hi Michel,

It looks like xrange isn't available anymore in python 3 and that we are technically using the old xrange from python 2 when we use range in python 3.

range was dropped in python 2 and the xrange from python 2 was renamed to range in python 3.

I guess it was decided that xrange worked better for most cases and we didn't really need both implementations.

In python 2, range would generate a static list in memory of all the numbers. Whereas, xrange would generate each number as needed which conserves memory for large ranges. They both essentially worked the same though from a usage perspective.

I think that if you needed the old behavior of range in python 2 then you could do list(range(10)) in python 3

I hadn't seen Kenneth's comment yet when I responded.

Name:GoogleSearch orJonathan Sum
Name:GoogleSearch orJonathan Sum
5,039 Points

thx Jason Anello. I love cheating!:) I will try to learn everything u ve posted from above.

Nicholas Wilky
Nicholas Wilky
3,973 Points

Hi Jason,

I don't understand what this bit of code is doing from the example using enumerate. list_of_tuples.append( (iterable_1[index], item2) ) How is this combining the value of iterable1 at index 0 with the value of iterable2 at index 0?

Pracheeti Maheshwari
Pracheeti Maheshwari
1,294 Points

Here is my solution using enumerate( ), but I still had to use append.

def combo(iter1, iter2):
  combo_list = []
  for index, value in enumerate(iter1):
    tuple = value, iter2[index]
    combo_list.append(tuple)
  return combo_list

tuple is a builtin type and shouldn't be used to name varaibles

Joseph Kato
Joseph Kato
35,340 Points

Here's one option:

def combo(iter1, iter2):
  return list(zip(iter1, iter2))

This uses the built-in zip() function which, as stated in the documentation, is designed to "make an iterator that aggregates elements from each of the iterables."

Abhishek Kulkarni
Abhishek Kulkarni
4,405 Points
def combo(arg1 , arg2):
    list(arg1)
    list(arg2)
    return [(arg1[i] , arg2[i]) for i in range(len(arg1))]
def combo(iterable1, iterable2):
    combo_values = map(lambda i, j: zip(i, j), iterable1, iterable2)
    return combo_values[0]

# OR

def combo(iter1, iter2):
    return  [zip(a, b) for a,b in map(lambda x, y: [x,y] , iter1, iter2)][0]
Melanie -
seal-mask
.a{fill-rule:evenodd;}techdegree
Melanie -
Python Web Development Techdegree Student 1,493 Points
def combo(a, b):
    return zip(a,b)

I see how the point of the exercise is to build zip() on your own but simple code is just prettier ¯_(ツ)_/¯

Hi Melanie,

Check the zip solution in my answer. You have to convert the result to a list if you want to use that.

Murat Mermerkaya
Murat Mermerkaya
2,346 Points

Bummer! Don't use zip()! I know it exists but the point of this challenge is to solve the problem yourself. Kenneth Love

You fixed the bug :)

Saundra Castaneda
Saundra Castaneda
14,606 Points
def combo(one,two):
    tuple_list=[]

    for thing in one:
        tuple_list.append((one[one.index(thing)], two[one.index(thing)]))

    return tuple_list
David Smith
David Smith
10,577 Points

I really enjoyed this challenge. I, like many, used zip at first and then I build my own zip function to solve that problem. While its not as good as the real zip it worked. Not the most elegant but I was happy with it. NOTE: If you try to copy and paste this it will fail because the code challenge looks for the word 'zip' so just change it to pip or something.

def my_zip(it_a, it_b):
    i = 0
    new_dict = {}
    for items in it_a:
        new_dict[items] = it_b[i]
        i +=1
    return new_dict


def combo(ordera, orderb):
    my_dict = my_zip(ordera, orderb)
    a_list = []
    final_list = []
    for key, value in my_dict.items():
        a_list = tuple([key, value])
        final_list.append(a_list)
    return(final_list)
J llama
J llama
12,631 Points

Awful challenge... When have we used enumerate or zip? NEVER.. Plan things a little better for us mr love!

David Smith
David Smith
10,577 Points

While I do agree we had not used it up until that point, I do believe throughout all their courses a certain level of self-study and exploration is expected.

J llama
J llama
12,631 Points

David Smith didn't ask for your opinion

Here is how I did it

def combo(iterable_1,iterable_2):
    list_of_tuples = []
    for index, item in enumerate(iterable_2, start = iterable_1[0]):
        list_of_tuples.append((index,item))
    return list_of_tuples