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

Getting 'list index out of range' on Challenge

I'm really not too sure what's happening in this challenge but I was in fact (in a real round-about way) able to get something that worked. Well, it did in my REPL at least, however, whenever I submit it, I get the error:

list index out of range

In my Python REPL everything looks perfect! Please help.

def combo(iter1, iter2):
  output = []
  iter1 = list(str(iter1))
  iter2 = list(str(iter2))
  for index, value in enumerate(iter1):
    tupleObj1 = value
    tupleObj2 = iter2[index]
    tupler = output.append((tupleObj1, tupleObj2))
  print(output)

Also, please help in general with this challenge. I know my code above is ugly. If there are better ways for me to do something, please let me know.

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

You need to add a return statement in place of the print statement. The .append() method does not return anything, so the tupler = is unnecessary.

The "index out of range" is due to the list(str(iter1)) statements. Converting an iterable such a [1, 2, 3] into a string then back into a list will convert the list syntax as well including brackets and commas. Since strings in lists are represented by 'a', this round-trip conversion added the extra quote symbols making the two iterables different lengths:

>>> iter1 = [1, 2, 3]
>>> iter2 = ['a', 'b', 'c']
>>> len(iter1)
3
>>> len(iter2)
3
>>> iter1 = list(str(iter1))
>>> iter2 = list(str(iter2))
>>> iter1
['[', '1', ',', ' ', '2', ',', ' ', '3', ']']
>>> iter2
['[', "'", 'a', "'", ',', ' ', "'", 'b', "'", ',', ' ', "'", 'c', "'", ']']
>>> len(iter1)
9
>>> len(iter2)
15

Good news is neither of these statements are needed. Comment them both out, with the other changes and your code will pass.

def combo(iter1, iter2):
  output = []
  # iter1 = list(str(iter1))
  # iter2 = list(str(iter2))
  for index, value in enumerate(iter1):
    tupleObj1 = value
    tupleObj2 = iter2[index]
    output.append((tupleObj1, tupleObj2))
  return output # <-- replace print

As for other solutions, here are some:

def combo(itr1, itr2):
    tup_list = []
    for index, num in enumerate(itr1):
        a = num
        b = itr2[index]

        new_tup = a, b
        tup_list.append(new_tup)
    return tup_list

def combo(itr1, itr2):
    tup_list = list()
    for num, letter in zip(itr1, itr2):
        a = num
        b = letter

        new_tup = a, b
        tup_list.append(new_tup)
    return tup_list


# this can be shortened to:
def combo(itr1, itr2):
    tup_list = list()
    for index, num in enumerate(itr1):
        tup_list.append((num, itr2[index]))
    return tup_list


def combo(itr1, itr2):
    tup_list = list()
    for num, letter in zip(itr1, itr2):
        tup_list.append((num, letter))
    return tup_list


# the previous one can be shortened even further
# since 'zip' returns one entry from each list as a tuple
def combo(itr1, itr2):
    tup_list = list(zip(itr1, itr2))
    return tup_list

# using a list comprehension 
def combo(itr1, itr2):
    return [(x, y) for idx, x in enumerate(itr1) for y in itr2[idx]]

Awesome! This was very helpful. Thank you!