Help wth for loop [Sampling Mission 7/14]

Hi,

I am doing this sampling mission where we have to stratify the data and then use it for random sampling Link to mission

I cannot understand the for loop provided in the solution.

wnba['Pts_per_game'] = wnba['PTS'] / wnba['Games Played']

# Stratifying the data in five strata
stratum_G = wnba[wnba.Pos == 'G']
stratum_F = wnba[wnba.Pos == 'F']
stratum_C = wnba[wnba.Pos == 'C']
stratum_GF = wnba[wnba.Pos == 'G/F']
stratum_FC = wnba[wnba.Pos == 'F/C']

points_per_position = {}
for stratum, position in [(stratum_G, 'G'), (stratum_F, 'F'), (stratum_C, 'C'),
                (stratum_GF, 'G/F'), (stratum_FC, 'F/C')]:
    
    sample = stratum['Pts_per_game'].sample(10, random_state = 0) # simple random sapling on each stratum
    points_per_position[position] = sample.mean()
    
position_most_points = max(points_per_position, key = points_per_position.get)

It would be a great help if someone can explain it or know which mission this was introduced so I can do it from there.

Hello Sandesh, fellow learner here!

A generic x, y kind of code is often used in reference to a pair of values in a tuple.

This here is an example of the kind of for loop you’re most familiar with - one that uses a single element:

list1 = [1, 2, 3, 4, 5, 6]
list2 = []

for i in list_1:
    list2.append(i * 2)  

print(list2) 

Just a glance of the above code is enough to know what the outputted list will look like:
[2, 4, 6, 8, 10, 12]

That worked easily because list1 was a list of integers. What if instead of being a list of integers, it was a list of tuples containing integers:

list3 = [(1, 2), (3, 4), (5, 6)]

list3 is very different. Instead of having 6 elements, it actually has only 3 elements. Each element is a tuple containing 2 integers. If you wanted to make a for loop using list3 to achieve the same output, how would you achieve the same list you printed earlier?

It’s simple enough! You just make a for loop like before that iterates through each element in the list, but before it begins iterating, you have to make sure the for loop is written such that each individual item in the tuple is accounted for!

The code we want would thus look like this:

list3 = [(1, 2), (3, 4), (5, 6)]
list4 = []

# x, y should be thought of as (x, y), each element referring to the 
# corresponding item in the tuple!
for x, y in list3: 
    list4.append(x * 2)
    list4.append(y * 2)

print(list4)

This gives us the same list printed before:
[2, 4, 6, 8, 10, 12]

In summary:
In the first example, the variable i was used to refer to each element in the list while iterating over it, because each element of the list was just an integer. In this second example, we’re now using two variables, x, y, to refer to each element in the new list, because list3 is a list of tuples, each tuple containing 2 integer values. x, y were therefore used to refer to the respective tuple values.

In the example you posted, you’re also iterating over a list of tuples:

# I'll add the parentheses around stratum, position to  
# make it easier to visualize:
for (stratum, position) in [(stratum_G, 'G'), (stratum_F, 'F'), (stratum_C, 'C'),
                (stratum_GF, 'G/F'), (stratum_FC, 'F/C')]

The same logic applies! In this for loop, the first variable, stratum, refers to the first item in the tuple (i.e. stratum_G or stratum_F), and the 2nd variable, position, refers to the 2nd item in the tuple (i.e. ‘G’ or ‘F’).

As to whether this has been explicitly covered, I don’t think it has been!! It might definitely be a good idea to include this concept explicitly in an existing mission, so people who haven’t come across it aren’t thrown for a loop.

On a side note, another place you might see something like a x, y tuple notation could be an example like the following:

x, y = 4, 5

# Instead of writing two lines like below to assign each individual value:
# x = 4
# y = 5
# We achieved the same using the tuple notation in one line of code

Or in a slightly more complex form, but in the same vein as above:

def plus_two(a, b):
    return a+2, b+2

x, y = plus_two(2, 3)

# Because the function plus_two returns 2 values in a tuple,
# you can also call the function as a method to assign the
# integers (4, 5) to x and y respectively. 
1 Like

Thank you @blueberrypudding85 ! This helps.

No worries!

It was a good idea for you to call attention to the fact that that particular kind of for loop had never been explored before in a mission!

Hi @blueberrypudding85, I am still struggling with understanding what the position does in the for loop. While the stratum selects the first item in the tuple, I am unsure if position selects the second item (‘G’, ‘F’ etc.) so that it’s stratum['G'] for instance.

Yep, that’s exactly right @popcsev. position just indicates the 2nd item in the tuple, as each individual tuple is being iterated over.

Hey @blueberrypudding85, Thanx a lot for the soulution… Brilliantly explained with detailed examples!! :clap: :clap:.

Wasted lot many hours foolishly, trying to understand the code all by myself - forgetting the fact that I could search/post for it on the Community.

Also, could you pls clarify whether the below two notations are same??
stratum_G = wnba[wnba.Pos == 'G']
stratum_G = wnba[wnba[Pos] == 'G']

Thanx again for all the help!!

Yep, these 2 should be the same!

Thank u @blueberrypudding85