0

I have lists (in python) which contains numbers who repeat then come other numbers then return again, like this:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 1]

I want to convert it to a new list where I avoid repetitiveness of numbers, like that:

['1*9', '2*2', '1*2', '3*3', '1*1'] 
  • Can you be specific about the rules for the output. Should numbers be in list order? Are you only counting duplicates within a single run length? – tdelaney Jun 27 '20 at 20:36
  • yes, numbers should be in list order, I have lists of temperature movement over time, each list represent the daily temperature movement where some number come and go, usually I use visualisation to see fluctuation, but I want to create list so I add it to data frame and check visually the movement of data – Khaled Koubaa Jun 27 '20 at 20:51
  • 1
    I'm voting to close this question as *needing more focus* since it could easily be split into two separate questions: how to count consecutive duplicates, and how to join the resulting values into strings. Both questions were already answered before. See [What's the most Pythonic way to identify consecutive duplicates in a list?](https://stackoverflow.com/q/6352425/7851470) and, for example, [Efficiently concatenate two strings from tuples in a list?](https://stackoverflow.com/q/54943449/7851470). – Georgy Jun 28 '20 at 17:06

5 Answers5

7
from itertools import groupby

numbers = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 1]

print([f"{key}*{len(list(group))}" for key, group in groupby(numbers)])

Output:

['1*9', '2*2', '1*2', '3*3', '1*1']
>>> 
Paul M.
  • 10,481
  • 2
  • 9
  • 15
2

You can build up a list of 2-element lists containing [element, count] and then convert it into your string format at the end.

a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 1]

b = []
for i in a:
    if not b or b[-1][0] != i:
        b.append([i, 1])   # a new element - append and start the count at 1
    else:
        b[-1][1] += 1  # a duplicate - increment the count

counts = ['{}*{}'.format(*l) for l in b]

print(counts)

This gives:

['1*9', '2*2', '1*2', '3*3', '1*1']
alani
  • 12,573
  • 2
  • 13
  • 23
0

The desired result can be achieved using the generator:

def gen(ll):
    v, q = None, -1
    for x in ll:
        if q < 0 or v != x:
            if q > 0:
                yield v, q
            v, q = x, 0
        q += 1
    yield v, q

ll = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 1]

print([f'{v}*{q}' for v, q in gen(ll)])

Output:

['1*9', '2*2', '1*2', '3*3', '1*1']

Demo.

Andrei Odegov
  • 2,925
  • 2
  • 15
  • 21
-1
list = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 1]
list2 = []

one =0
two =0
three =0

for i in list:
  if i == 1:
    one+=1
  if i == 2:
    two+=1
  if i == 3:
    three+=1

list2.append("1*"+str(one))
list2.append("2*"+str(two))
list2.append("3*"+str(three))

print(list2)
  • That only works for 3 previously known numbers. It also does not produce the desired output where a number that shows up a second time gets a new entry. – tdelaney Jun 27 '20 at 20:42
-1

You can do this :

         ll=[1,1,1,1,1,1,1,1,2,2,3,3,3]
         b=[]
         for i in ll:
            x=ll.count(i)
            t=str(i)+'*'+str(x)
            b.append(t)
         b=list(set(b))
         print(b)

This will be the output: ['1 * 8', '3 * 3', '2 * 2']

  • OP has sample input and desired output. Your code doesn't use the sample input, but when modified, doesn't produce the output. From OP's sample output I think that run lengths of repeated characters in list order is needed. – tdelaney Jun 27 '20 at 20:35