How can I find same values in a list and group together a new list?

52,800

Solution 1

Someone mentions for N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1] it will get [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]]

In other words, when numbers of the list isn't in order or it is a mess list, it's not available.

So I have better answer to solve this problem.

from collections import Counter

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
C = Counter(N)

print [ [k,]*v for k,v in C.items()]

Solution 2

Use itertools.groupby:

from itertools import groupby

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]

print([list(j) for i, j in groupby(N)])

Output:

[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

Side note: Prevent from using global variable when you don't need to.

Solution 3

You can use itertools.groupby along with a list comprehension

>>> l =  [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
>>> [list(v) for k,v in itertools.groupby(l)]
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

This can be assigned to the variable L as in

L = [list(v) for k,v in itertools.groupby(l)]

Solution 4

You're overcomplicating this.

What you want to do is: for each value, if it's the same as the last value, just append it to the list of last values; otherwise, create a new list. You can translate that English directly to Python:

new_list = []
for value in old_list:
    if new_list and new_list[-1][0] == value:
        new_list[-1].append(value)
    else:
        new_list.append([value])

There are even simpler ways to do this if you're willing to get a bit more abstract, e.g., by using the grouping functions in itertools. But this should be easy to understand.


If you really need to do this with a while loop, you can translate any for loop into a while loop like this:

for value in iterable:
    do_stuff(value)

iterator = iter(iterable)
while True:
    try:
        value = next(iterator)
    except StopIteration:
        break
    do_stuff(value)

Or, if you know the iterable is a sequence, you can use a slightly simpler while loop:

index = 0
while index < len(sequence):
    value = sequence[index]
    do_stuff(value)
    index += 1

But both of these make your code less readable, less Pythonic, more complicated, less efficient, easier to get wrong, etc.

Solution 5

You can do that using numpy too:

import numpy as np

N = np.array([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
counter = np.arange(1, np.alen(N))
L = np.split(N, counter[N[1:]!=N[:-1]])

The advantage of this method is when you have another list which is related to N and you want to split it in the same way.

Share:
52,800

Related videos on Youtube

Siii
Author by

Siii

Designer, python, pi, ardunio, doodler

Updated on October 20, 2020

Comments

  • Siii
    Siii over 3 years

    From this list:

    N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
    

    I'm trying to create:

    L = [[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]
    

    Any value which is found to be the same is grouped into it's own sublist. Here is my attempt so far, I'm thinking I should use a while loop?

    global n
    
    n = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] #Sorted list
    l = [] #Empty list to append values to
    
    def compare(val):
       """ This function receives index values
       from the n list (n[0] etc) """
       
       global valin
       valin = val
    
       global count
       count = 0
    
        for i in xrange(len(n)):
            if valin == n[count]: # If the input value i.e. n[x] == n[iteration]
                temp = valin, n[count]
                 l.append(temp) #append the values to a new list
                 count +=1
            else:
              count +=1
        
    
    for x in xrange (len(n)):
        compare(n[x]) #pass the n[x] to compare function
    
    • Bhargav Rao
      Bhargav Rao almost 9 years
      Here is my attempt so far ... Please mention if you have faced any problems with your code.
    • Paul Rooney
      Paul Rooney almost 9 years
      Why store all the numbers? Why not just collapse it into a list of tuples containing two values. The number itself and the number of times that number occurs.
  • Bhargav Rao
    Bhargav Rao almost 9 years
    Really nice answer (I like brute-force), But can you think of a way using a while loop? In OP's words I'm thinking I should use a while loop?
  • abarnert
    abarnert almost 9 years
    @BhargavRao: Well, you can always translate any for loop into a while loop. But why do you want to?
  • Bhargav Rao
    Bhargav Rao almost 9 years
    For this problem the for loop is better suited. Unlike C, py translations are not that straight-forward, though they are quite easy. I just asked to give the OP a fair idea of the while loop and it's complications. D̶o̶ ̶c̶o̶n̶s̶i̶d̶e̶r̶ ̶d̶o̶i̶n̶g̶ ̶t̶h̶a̶t̶ ̶i̶n̶ ̶y̶o̶u̶r̶ ̶s̶p̶a̶r̶e̶ ̶t̶i̶m̶e̶ Well good one there :)
  • Andrzej Pronobis
    Andrzej Pronobis almost 9 years
    Note: the list needs to be sorted according to the same key used by groupby to achieve the result expected in the question. Otherwise e.g. for N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1] you will get [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]].
  • Siii
    Siii almost 9 years
    Fantastic Tony! I did run in to issues with indexing using the itertools solution so this method worked well as i didn't need to sort the list before hand! Thank you once again!
  • Spider
    Spider almost 6 years
    @Sam Bruns . Your method is not stable when , for example,N has random values. If you want to check what I am trying to say, just put random.shuffle(N) right after you create list N. Then, you will see output is not the same while the code by @Burger King is stable.
  • aldeb
    aldeb almost 6 years
    @Spider: The array containing random values is not in any way a requirement specified by the OP. Please make sure you fully understand the question before commenting.
  • Spider
    Spider almost 6 years
    @SamBruns I made exactly sure by saying: "your method is not stable" and there is nothing wrong to complement your answer in order to show the audience that if someone wants to use in any cases like that. Your method definitely fails when it comes to "un-sorted" list and ... you make sure please, my comment what I m trying to say.
  • aldeb
    aldeb almost 6 years
    @Spider: What you define as "stable" and "not stable" is arbitrary here. Maybe the OP DO wants the solution to behave that way. One can think of many use cases where grouping all the values into a single list is not wanted. While the behavior you're pointing out can be mentioned as a note (as it already was in the first comment), it cannot in any way be defined as not stable. Please don't make your assumptions... requirements.