Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping over a dictionary to display key and values in order of a value

I am attempting to loop over a dictionary with a for loop to display keys and values in order of one of the value elements(the batting order number).

I can print the keys and values in the intended format, but I cannot figure out how to get the lines in the correct batting order.

I need to complete this task with logic in a for loop and without the use of lambda or a function. Here is what I have so far:

print ('Rays starters' + "\n")
rays_starters = {
    'DeJesus' : ['DH', 6, 299],
    'Loney' : ['1B', 4, 222],
    'Rivera' : ['C', 9, 194],
    'Forsythe' : ['2B', 5, 304],
    'Souza Jr' : ['RF', 2, 229],
    'Longoria' : ['3B', 3, 282],
    'Cabrera' : ['SS', 7, 214],
    'Kiermaier' : ['CF', 1, 240],
    'Guyer' : ['LF', 8, 274] }
for player in rays_starters:
    print (player + str(rays_starters[player]))
print ('\n' + 'Today\'s lineup' + '\n')
for player in rays_starters:
    batting_order = rays_starters.get(player)
    print('Batting ' + str(batting_order[1]) + ' : ' + str(batting_order[0]) + ' ' + player + ' ,current avg: ' + str(batting_order[2]))   

The output should look like this:

Rays starters

DeJesus ['DH', 6, 299]
Loney ['1B', 4, 222]
Rivera ['C', 9, 194]
Forsythe ['2B', 5, 304]
Souza Jr ['RF', 2, 229]
Longoria ['3B', 3, 282]
Cabrera ['SS', 7, 214]
Kiermaier ['CF', 1, 240]
Guyer ['LF', 8, 274]

Today's lineup

Batting 1 : CF Kiermaier ,current avg: 240
Batting 2 : RF Souza Jr ,current avg: 229
Batting 3 : 3B Longoria ,current avg: 282
Batting 4 : 1B Loney ,current avg: 222
Batting 5 : 2B Forsythe ,current avg: 304
Batting 6 : DH DeJesus ,current avg: 299
Batting 7 : SS Cabrera ,current avg: 214
Batting 8 : LF Guyer ,current avg: 274
Batting 9 : C Rivera ,current avg: 194

My output does in fact look exactly like this with the exception of the batting order being out of order. Please help me get on the right track and remember I am trying to learn here so any helpful criticism is welcome!

like image 561
Wes Avatar asked Dec 19 '22 03:12

Wes


2 Answers

Here's an efficient way since we know there are going to be 9 batters.

lineup = [None] * 9
for player, stats in rays_starters.items():
    lineup[stats[1]-1] = player, stats
print ('\nToday\'s lineup\n')
for player, batting_order in lineup:
    print('Batting ' + str(batting_order[1]) + ' : ' + str(batting_order[0]) + ' ' + player + ' ,current avg: ' + str(batting_order[2]))

All we are doing is initializing an array of 9 elements and using the batting order to map the player and stats as a tuple to the correct array index. Then we loop through the array of player and statistics tuples, and print the desired formatted output. This is O(n).

This concept is basically derived from Radix sort, or, more specifically, a very simple case of Counting sort where all the frequences are 1 and the "key function" is just subtracting 1 from the batting order to get an array index.

As @PadraicCunningham notes in the comments, this can theoretically be used for any number of batters by using the len function.

like image 106
Shashank Avatar answered Dec 21 '22 17:12

Shashank


Dictionaries do not have an order, so you cannot sort them. You can however iterate over its values in a sorted manner. For this, you can use sorted() and a key function that specifies how to get the value when passed a (key, value) tuple:

for player, batting in sorted(rays_starters.items(), key=lambda x: x[1][1]):
    print('Batting {1} : {0} {player}, current avg: {2}'.format(*batting, player=player))

For your rays_starters dictionary, this will yield the following result:

Batting 1 : CF Kiermaier, current avg: 240
Batting 2 : RF Souza Jr, current avg: 229
Batting 3 : 3B Longoria, current avg: 282
Batting 4 : 1B Loney, current avg: 222
Batting 5 : 2B Forsythe, current avg: 304
Batting 6 : DH DeJesus, current avg: 299
Batting 7 : SS Cabrera, current avg: 214
Batting 8 : LF Guyer, current avg: 274
Batting 9 : C Rivera, current avg: 194

If you can’t specify such a key function, you will have to implement the sorting on your own. For this, you can first turn the dictionary into a list first which you then sort. In order to not need a key function, you should construct that list so the value you want to sort by is the first in the list:

data = []
for player, batting in rays_starters.items():
    data.append((batting[1], player, batting[0], batting[2]))

# now sort the list
data.sort()

# and iterate and print
for player in data:
    print('Batting {0} : {1} {2}, current avg: {3}'.format(*player))

You can also create the data list using a list comprehension:

data = [(b[1], p, b[0], b[2]) for p, b in rays_starters.items()]
like image 37
poke Avatar answered Dec 21 '22 17:12

poke