1

I have an array, for example [A,A,A,B,B,C,A,A,D,D,D,B]

I want to count the entries and convert it to this [3A,2B,1C,2A,3D,1B]

I have tried a load of if else type logic but I'm having issues. Is there a neat way to do this?

2
  • 1
    You say you are having issues, what is the issue you are having? Do you have some starter code you could show so I could see how far you've gotten? Commented Jan 17, 2022 at 1:53
  • It turned into a mess of if else statements and I knew there would be a better way. I'm going to try some of the answers tomorrow. Thanks for responding. Commented Jan 17, 2022 at 2:30

3 Answers 3

4

Seems like a good use of itertools.groupby:

from itertools import groupby

l = ['A','A','A','B','B','C','A','A','D','D','D','B']

[f'{len(list(g))}{k}' for k, g in groupby(l)]
# ['3A', '2B', '1C', '2A', '3D', '1B']
Sign up to request clarification or add additional context in comments.

3 Comments

[list(g) for k,g in list(groupby(l))] gives empty lists and removing list() from groupby(l) works well why is that so?
@Bibhav the groups with groupby are all tied to a single iterator so calling list(groupby(l)) uses up the iterator of the groups. This is explained in the docs with: "Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list". This allows it to work efficiently with large iterators.
Thank you, this perfectly solved my needs. I tried to upvote but I need more reputation first, I will get on that!
0

This is one way to solve this problem.

letters = ['A', 'A', 'A', 'B', 'B', 'C', 'A', 'A', 'D', 'D', 'D']

previous_letter = letters[0]
counter = 1
res = list()
for i in range(1, len(letters)):
    current_letter = letters[i]
    if current_letter == previous_letter:
        counter += 1

    else:
        res.append(f"{counter}{current_letter}")
        previous_letter = letters[i]
        counter = 1

res.append(f"{counter}{previous_letter}")
print(res)

The trick is in checking a change of letters and keeping track of the count.

1 Comment

Hi, thanks for your response. This is what I was trying but I was hoping for a simpler solution. I found one above.
0

you could try using list.count() to get the number of times the first item appears then use list.pop(list.index()) in a for loop to remove all occurences of the first item, do this in a while loop until len(lst) returns 0

out = []
while len(lst) > 0:
    s = lst[0]
    c = 0
    while len(lst) > 0:
        if lst[0] == s:
            c += 1
            lst.pop(0)
    out.append(f"{c}{s}")

2 Comments

Seems like this produces ['5A', '3B', '1C', '3D'] with the poster's input, but they want [3A,2B,1C,2A,3D,1B].
@Mark thank you for the comment, I didn't read the question correctly I will edit my answer

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.