1

I wish to convert a string into a nested tuple for instance:

string = 'Jane A 3 B- 3 F 1#Bob C+ 2 D+ 3#Chris C 4 C 3 C- 2'

As you can see, the string is not normal with # signs and white-spaces in place of a comma. The # sign is what represents the number of names for which I have to compute some data that follows after each name. So I used string.split('#') to create 3 separate strings and from there, I used a for loop to get this on the first iteration:

['A', 3, 'B-', 3, 'F', 1]

The reason why 'Jane' is missing from the list is because I only need to take the values, whether it be a string or an integer, and make a nested tuple out of them. Thus, I wish to convert this list into a nested tuple that looks like:

[('A', 3), ('B-', 3), ('F', 1)]

I will greatly appreciate any help or suggestions.

2 Answers2

1

I dont know if there is a better way, but here we go:

input = ['A', 3, 'B-', 3, 'F', 1]

l1 = input[::2] # get even
l2 = input[1::2] # get odd

tuples = list(zip(l1,l2)) # zip them together
# yes it could be wrote `tuples = list(zip(input[::2],input[1::2]))`

print (tuples)

Output

[('A', 3), ('B-', 3), ('F', 1)]

Try it online!

aloisdg
  • 22,270
  • 6
  • 85
  • 105
0

using regular expressions

>>> import re
>>> [[(mark, int(count))
      for mark, count in map(str.split,
                             re.findall(r'[A-Z][+-]? \d+', student_data))]
     for student_data in string.split('#')]
[[('A', 3), ('B-', 3), ('F', 1)],
 [('C+', 2), ('D+', 3)],
 [('C', 4), ('C', 3), ('C-', 2)]]

Step-by-step explanation

  1. We're separating students (let's call them so) from each other since we need to store their "marks" (or what does these A/B/C/D with +/- mean?) in different containers:

    string.split('#')
    
  2. For each student we're searching "mark" data using regular expression

    [A-Z][+-]? \d+
    

    which can be read like

    any capital Latin letter (which optionally may be followed by + or - sign) and a whitespace followed by digits

    and pass it and student's substring to re.findall function. After that we will have something like:

    >>> [re.findall(r'[A-Z][+-]? \d', student_data) for student_data in string.split('#')]
    [['A 3', 'B- 3', 'F 1'], ['C+ 2', 'D+ 3'], ['C 4', 'C 3', 'C- 2']]
    
  3. Finally we can use str.split method to separate letters with +/- from digits and iterate over this pairs converting second coordinates to int.

Further reading

Azat Ibrakov
  • 9,998
  • 9
  • 38
  • 50
  • Yes the +/- signs are letter grades and I need to write a function that takes a weird string and determines whether any of the students in the list make the dean's list. So far I have around 64 lines of code with proper spacing between functions but it doesn't work. What I mean is that I use a helper function to determine their gpa which takes a tuple as its argument. When I input the tuples from my string manually, it gives the right answer but when I try to return it in my program with the string function included, I get an error. – Seungsoo Im Jul 26 '18 at 16:10
  • I think you would understand what I mean if you saw my code. I know what I am supposed to do but I think its something really trivial that I'm missing. If you can help me I'd greatly appreciate it. – Seungsoo Im Jul 26 '18 at 16:12
  • I had a previous assignment where I had to write a function that took a list of tuples and use a dictionary to determine the overall gpa. This assignment I am currently working on is to write a function that calls on the previous one to see whether a student makes the deans list. I just figured I can turn the argument into a list of tuples which the helper function takes and it will return the proper value but it doesn't work and its getting frustrating. – Seungsoo Im Jul 26 '18 at 16:15
  • @SeungsooIm: and where is your code? – Azat Ibrakov Jul 26 '18 at 20:44