0

Please help on this. I have an input like this:

 a = """A|9578
 C|547
 A|459
 B|612
 D|53
 B|6345
 A|957498
 C|2910"""

I want to print in sorted way the numbers related with each letter like this:

 A_0|459
 A_1|957498
 A_2|9578
 C_0|2910
 C_1|547
 B_0|612
 B_1|6345
 D_0|53

So far I was able to store in array b the letters and numbers, but I'm stuck when I try to create dictionary-like array to join a single letter with its values, I get this error.

 b = [i.split('|') for i in a.split('\n')]
 c = dict()
 d = [c[i].append(j) for i,j in b]
 >>> d = [c[i].append(j) for i,j in b]
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 1, in <listcomp>
 TypeError: list indices must be integers or slices, not str

I'm working on python 3.6 just in case. Thanks in advance.

Ger Cas
  • 2,188
  • 2
  • 18
  • 45

1 Answers1

1

We'll split the string into pairs, sort those pairs, then use groupby and enumerate to come up with the indices.

from itertools import groupby
from operator import itemgetter

def process(a):
    pairs = sorted(x.split('|') for x in a.split())
    groups = groupby(pairs, key=itemgetter(0))
    for _, g in groups:
        for index, (letter, number) in enumerate(g):
            yield '{}_{}|{}'.format(letter, index, number)

for i in process(a): print(i)

gives us

A_0|459
A_1|957498
A_2|9578
B_0|612
B_1|6345
C_0|2910
C_1|547
D_0|53
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
  • Hi Patrick, thanks so much for your help. It seems to work fine your solution. I'm very new with python and have some doubts. For example, how yield work? Is possible to print the output values without using yield and print function instead of it? Thanks – Ger Cas Aug 02 '18 at 05:08
  • Using `yield` turns a function into a generator, which allows it to "return" many values instead of just one. You could replace `yield` with `print`. I prefer the `yield` version because if you change your mind later, and want to put the values in a list instead of printing them, you can do `list(process(a))` – Patrick Haugh Aug 02 '18 at 11:57
  • Thanks for the reply. Last doubt. The function argument is "s" but I don't see where "s" is used within the function. How does this work? – Ger Cas Aug 02 '18 at 13:48
  • @GerCas that was a mistake, it should be `a`. – Patrick Haugh Aug 02 '18 at 13:50
  • I asked because if I enter the function as originally posted by you, this is like this `def process(s)` and then I call the function `for i in process(a): print(i)` it works for me! even when argument `s` is not used in function body. – Ger Cas Aug 02 '18 at 16:29
  • Because it inherits the name `a` from the global scope. – Patrick Haugh Aug 02 '18 at 16:31
  • Understood. Thanks – Ger Cas Aug 02 '18 at 18:57