Reputation: 2224
Say I have a list [2, 3, 7, 2, 3, 8, 7, 3]
I would like to produce lists that contain identical values from the list above.
Expected Output something like:
[2, 2]
[3, 3, 3]
[7, 7]
[8]
The order that these lists are produced doesn't matter.
Upvotes: 4
Views: 131
Reputation: 42678
Best approach is an O(n)
solution with collections.defaultdict
:
>>> l = [2, 3, 7, 2, 3, 8, 7, 3]
>>> d = defaultdict(list)
>>> for e in l:
... d[e].append(e)
...
>>> d
defaultdict(<class 'list'>, {2: [2, 2], 3: [3, 3, 3], 7: [7, 7], 8: [8]})
>>> d.values()
dict_values([[2, 2], [3, 3, 3], [7, 7], [8]])
Alternatively you can use itertools.groupby
with sorted list:
>>> for _, l in itertools.groupby(sorted(l)):
... print(list(l))
...
[2, 2]
[3, 3, 3]
[7, 7]
[8]
Or a list comprehension with collections.Counter
:
>>> from collections import Counter
>>> [[i]*n for i,n in Counter(l).items()]
[[2, 2], [3, 3, 3], [7, 7], [8]]
As I post, the defaultdict solution is O(n)
and faster than the other aproaches. Here are the tests:
from timeit import timeit
setup = (
"from collections import Counter, defaultdict;"
"from itertools import groupby;"
"l = [2, 3, 7, 2, 3, 8, 7, 3];"
)
defaultdict_call = (
"d = defaultdict(list); "
"\nfor e in l: d[e].append(e);"
)
groupby_call = "[list(g) for _,g in groupby(sorted(l))]"
counter_call = "[[i]*n for i,n in Counter(l).items()]"
for call in (defaultdict_call, groupby_call, counter_call):
print(call)
print(timeit(call, setup))
Results:
d = defaultdict(list);
for e in l: d[e].append(e);
7.02662614302244
[list(g) for _,g in groupby(sorted(l))]
10.126392606005538
[[i]*n for i,n in Counter(l).items()]
19.55539561196929
Here is the live test
Upvotes: 5
Reputation: 4664
This answer is with list-comprehension:
l = [2, 3, 7, 2, 3, 8, 7, 3]
print(*[[i]*l.count(i) for i in set(l)], sep='\n')
OUTPUT :
C:\Users\Desktop>py x.py
[8]
[2, 2]
[3, 3, 3]
[7, 7]
Moreover, the output can be made exactly as yours with sorted()
method
l = [2, 3, 7, 2, 3, 8, 7, 3]
print(*sorted([[i]*l.count(i) for i in set(l)]), sep='\n')
OUTPUT:
C:\Users\Desktop>py x.py
[2, 2]
[3, 3, 3]
[7, 7]
[8]
EDIT : As the answer gets upvoted I want to explain the code in detail to be helpful as much as I can.
The code is this:
print(*[[i]*l.count(i) for i in set(l)], sep='\n')
Using set(l)
eliminates duplicated values and remains only [2, 3, 7, 8]
in the list. Later, in [i]
we put each element of set(l)
in a new list. We count how many time i
element(i
is a element in set(l
)) occurs in native list l
(l = [2, 3, 7, 2, 3, 8, 7, 3]
). And in [i]*l.count(i)
i
become l.count(i)
times in the new list. List-comprehension method gets the all values after iterations are done and pack it in a list and returns list. *
sign at the beginning is for unpacking the values in the returned list. And finally *print()*
keyword sep='\n'
put a '\n'
after each elements in the unpacked list. Without it this could have been done like:
for j in [[i]*l.count(i) for i in set(l)]:
print(j)
Upvotes: 2
Reputation: 11665
Try this
l = [2, 3, 7, 2, 3, 8, 7, 3]
for i in set(l):
print([i]*l.count(i))
Output:
[8]
[2, 2]
[3, 3, 3]
[7, 7]
Upvotes: 4
Reputation: 3447
Here's a short way of doing it by using Counter
from collections import Counter
my_dict = Counter([2, 3, 7, 2, 3, 8, 7, 3]) # returns {3: 3, 2: 2, 7: 2, 8: 1}
new_list = [[k] * v for k,v in my_dict.items()]
Outputs:
[[2, 2], [3, 3, 3], [7, 7], [8]]
Upvotes: 3
Reputation: 12990
One way to do this is to use a simple dictionary:
l = [2, 3, 7, 2, 3, 8, 7, 3]
groups = {}
for n in l:
groups.setdefault(n, []).append(n)
print(list(groups.values()))
# [[2, 2], [3, 3, 3], [7, 7], [8]]
Upvotes: 3
Reputation: 318
I think you may try collections.Counter, and get different keys and its count in this list.
from collections import Counter
l = [2, 3, 7, 2, 3, 8, 7, 3]
c =Counter(l)
print(c) ## result: {3: 3, 2: 2, 7: 2, 8: 1}
Upvotes: 2
Reputation: 16966
Doing this operation in Numpy array would be efficient
a= np.array([2, 3, 7, 2, 3, 8, 7, 3])
[a[a==i] for i in np.unique(a)]
Output:
[array([2, 2]), array([3, 3, 3]), array([7, 7]), array([8])]
Upvotes: 2