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)

1

6 Answers 6

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]
Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, ignore previous comment - this is beautiful. works fine. Thank you!
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.

Comments

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)

1 Comment

can you please clearly explain the line d = dict(itertools.zip_longest(*[iter(biology_score.split(","))] * 2, Thanks!
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.

Comments

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]))

Comments

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}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.