3

I have the following code that takes a string biology_score and after splitting it, converts it into a string ('b'). The desired output is to produce what I have constructed manually below (a list of users with their corresponding scores)

I would be interested in the most efficient way to construct a for loop to achieve this with a list. Note: I am aware that the best way to approach this would be a dictionary, but these purposes I want to use a list.

Code:

biology_score="user1,30,user2,60,user3,99"
print(biology_score[1]) #for testing purposes
b=biology_score.split(",")
print(b) #prints lists
print(b[2]) #prints element in index 2 in the list

#desired output
print(b[0],"scored",b[1])
print(b[2],"scored",b[3])
print(b[4],"scored",b[5])

#create a for loop to do the above

Required answer

  1. The most elegant solution (for loop to produce the above by looping through the list)

  2. The easiest/quickest method to convert the string to a dictionary, using the least number of steps, and then achieving the same output (user: score)

Tomalak
  • 332,285
  • 67
  • 532
  • 628
Compoot
  • 2,227
  • 6
  • 31
  • 63
  • Your second question is answered here: https://stackoverflow.com/questions/4576115/convert-a-list-to-a-dictionary-in-python – Tomalak Sep 06 '17 at 08:04

6 Answers6

3

I'm not sure if this is what you're looking for:

biology_score="user1,30,user2,60,user3,99"
print(biology_score[1]) #for testing purposes
b=biology_score.split(",")
biology_dict = {}

for i in range(0, len(b), 2):  #looks only at even indices
    print(b[i],"scored",b[i+1])
    biology_dict[b[i]] = b[i+1]
chngzm
  • 608
  • 4
  • 13
1

If this is what you need.

#create a for loop to do the above
for i in range(0,len(b)-1,2):
  print(b[i],"scored",b[i+1])

Note: Python versions <3.6 does not support element orders. So, when you go with dict, the order might not be retained.

voidpro
  • 1,652
  • 13
  • 27
1

One of the options is to use dictionary

If the iterables are of uneven length, missing values are filled-in with fillvalue

import itertools    
d = dict(itertools.zip_longest(*[iter(biology_score.split(","))] * 2, 
fillvalue=""))

for k, v in d.items():
    print(k,'scored', v)
Linas Fx
  • 396
  • 2
  • 10
  • can you please clearly explain the line d = dict(itertools.zip_longest(*[iter(biology_score.split(","))] * 2, Thanks! – Compoot Sep 06 '17 at 08:35
0

You can use the grouper recipe from the itertools module:

import itertools
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

Then:

for user, score in grouper(b, 2):
    print(user, 'scored', score)

To make a dictionary:

dictionary = dict(grouper(b, 2))
for user, score in dictionary.items():
    print(user, 'scored', score)

Or use an OrderedDict if the original order of the items should be preserverd.

Roel Schroeven
  • 1,778
  • 11
  • 12
0

Mostly a rewrite of @chngzm's answer, and it's probably unsuitable for your teaching purposes, but using a generator is quite nice:

def user_scores(scores):
  s = scores.split(",")
  for idx in range(0, len(s), 2):
    yield s[idx], s[idx+1]

biology_score="user1,30,user2,60,user3,99"

for user, score in user_scores(biology_score):
  print("{0} scored {1}".format(user, score))

biology_dict = dict(s for s in user_scores(biology_score))
for user in biology_dict:
  print("{0} scored {1}".format(user, biology_dict[user]))
Glenn Rogers
  • 351
  • 2
  • 4
0

One Pythonic way to get the desired result is to use zip:

biology_score = "user1,30,user2,60,user3,99"
values = biology_score.split(',')
print(dict(zip(values[::2], values[1::2])))
# {'user2': '60', 'user3': '99', 'user1': '30'}

If you want integer scores, you can use map:

print(dict(zip(values[::2], map(int, values[1::2]))))
# {'user2': 60, 'user3': 99, 'user1': 30}
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124