How can I find same values in a list and group together a new list?
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.
Related videos on Youtube
Comments
-
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 almost 9 yearsHere is my attempt so far ... Please mention if you have faced any problems with your code.
-
Paul Rooney almost 9 yearsWhy 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 almost 9 yearsReally 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 almost 9 years@BhargavRao: Well, you can always translate any
for
loop into awhile
loop. But why do you want to? -
Bhargav Rao almost 9 yearsFor 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 thewhile
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 almost 9 yearsNote: 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 almost 9 yearsFantastic 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 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 putrandom.shuffle(N)
right after you create listN
. Then, you will see output is not the same while the code by @Burger King is stable. -
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 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 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.