Compoot
Compoot

Reputation: 2387

How to write an indexed loop over a list in Python?

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)

Upvotes: 3

Views: 112

Answers (6)

Eric Duminil
Eric Duminil

Reputation: 54223

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}

Upvotes: 0

Glenn Rogers
Glenn Rogers

Reputation: 351

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

Upvotes: 0

Linas Fx
Linas Fx

Reputation: 396

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)

Upvotes: 1

Roel Schroeven
Roel Schroeven

Reputation: 1822

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.

Upvotes: 0

voidpro
voidpro

Reputation: 1672

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.

Upvotes: 1

chngzm
chngzm

Reputation: 628

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]

Upvotes: 3

Related Questions