I don't understand the solution in Step 17/18

Hey guys, im currently at the exercise “Thread Shed”. At Step 17 I get confused about the proper solution, which is given within the Project Walkthrough.
Im really getting confused, that kind of confusion that makes you feel like “I don’t understand anymore how the world works”

https://www.codecademy.com/courses/learn-python-3/projects/thread-shed

The solution looks like this:

thread_sold_split = []
for sale in thread_sold:
  for color in sale.split("&"):
    thread_sold_split.append(color)

What happens in the line ‘for color in sale.split(“&”)’?
I mean I think it’s supposed to iterate through a list in a list (a loop nested in another). That means in this case, because there is just one List and in that list there are several strings, I will iterate through the letters of each string in that list.

But if I print the color before the last line, which appends the color to the new list, I don’t see the single letters printed but the whole string (the color for example: white, green, blue etc.) and not (w, h, i, t, e …).

But if I do write a code like

thread_sold_split = []
for sale in thread_sold:
  for color in sale:
    sale.split("&")
    thread_sold_split.append(color)

it prints me every single letter, which im supposed to receive but still with the “&” - sign. So the sale.splitt(“&”) didn’t do anything.

But changing my code to:

hread_sold_split = []
for sale in thread_sold:
  for color in sale:
    splitted = sale.split("&")
  thread_sold_split.append(splitted)

it obviously filters out the “&”-sign and returns the whole word into a new list. But now I have a list in a list, which im not supposed to have. I mean, I know why, because I saved the changes of ‘sale.split(“&”)’ in an empty list called ‘splitted’.

So what’s going on in the solutions line ‘for color in sale.split(“&”)’ ? Why do I get whole words if I print (color) and not the single letters?

for sale in thread_sold:
  for color in sale.split("&"):
    print(color)
    thread_sold_split.append(color)

Looking forward for some answers that gets me out of that confusion.

Kind regards

1 Like

I’m torturing myself trying to understand that exact same thing, and i still can’t understand it…

When you reach Step 17, thread_sold is a list of strings of the form:

# thread_sold
['white', 'white&blue', 'white&blue', 'white', ... 'white&blue&red', ...]

Now, the goal is that we want a list thread_sold_split in which the strings of single colors are added unchanged, while strings of multiple colors are broken down into single color strings so that the final structure would be:

# thread_sold_split
['white', 'white', 'blue', 'white', 'blue', 'white', ... 'white', 'blue', 'red', ...]

We could write a function and use if statements to differentiate between strings of single colors and strings of multiple colors (based on the absence/presence of the '&' character). Instead of going through all that extra work/code, we can accomplish the same task in a few lines using nested for loops.

The split method (documentation) acts on a string and returns a list of strings split using the character specified by us. A couple of examples will make it clear:

x = 'white'
y = x.split('&')
print(y) 
Output: ['white']
# A list with the original string is returned since no '&' character was found. 

x = 'white&blue&red'
y = x.split('&')
print(y)
Output: ['white', 'blue', 'red']
# A list with strings split upon the '&' character is returned.

With the above in mind, let’s revisit the code posted by you:

thread_sold_split = []
for sale in thread_sold:
  for color in sale.split("&"):
    thread_sold_split.append(color
  • thread_sold is a list of strings, so in every iteration of the for sale in thread_sold: loop, a string will be assigned to the loop variable sale.

  • In the nested loop, sale.split("&") will split the string using '&' as the separator. If sale is a single color string e.g. 'white', then the returned list will be ['white']. If sale is a multi-color string e.g. 'white&blue', then the returned list will be ['white', 'blue']. In the nested loop

for color in sale.split("&"):

the loop variable color will iterate over the lists returned by the split method.

# Suppose sale was 'white', then 
for color in sale.split("&"):
# will be equivalent to:
for color in ['white']:

# Suppose sale was 'white&blue', then 
for color in sale.split("&"):
# will be equivalent to:
for color in ['white', 'blue']:

Then, the nested loop appends each individual color to the thread_sold_split list,

thread_sold_split.append(color)

:checkered_flag:


For the other snippets posted by you,

thread_sold_split = []
for sale in thread_sold:
  for color in sale:
    sale.split("&")
    thread_sold_split.append(color)

In this version, sale is a string. The nested loop is iterating over this string and assigning each individual character to the loop variable color. The split method returns a new list. Since you are neither assigning the result of the split to any variable nor using it directly, so the statement does the split and then throws away the result. Since color is an individual character of the original string, so you will end up with thread_sold_split having a structure similar to:

# thread_sold_split
['w', 'h', 'i', 't', 'e', 'w', 'h', 'i', 't', 'e', '&', 'b', 'l', ...]

In the version,

thread_sold_split = []
for sale in thread_sold:
  for color in sale:
    splitted = sale.split("&")
  thread_sold_split.append(splitted)

sale will be a string. The nested loop will iterate over this string and in each iteration, a single character will be assigned to the loop variable color. You will split the sale string and assign it to the splitted variable. This will mean that splitted will be a list of string(s). Once the nested loop finishes, then you will append the stripped list to thread_sold_split so that you end up having a structure like:

[['white'], ['white', 'blue'], ['white', 'blue'], ['white'], ... ]
1 Like