1

I have a list [2,3,0,3] And want to generate a list

[1,0,1,2]

The reasoning is that 1 zero appears, no one appears, 1 two appears and 2 threes appear in the input list.

Is there a non for loopy procedural way to do this in python?

Sociopath
  • 13,068
  • 19
  • 47
  • 75
katiex7
  • 863
  • 12
  • 23

4 Answers4

4

You can use collections.Counter which finds count of elements:

from collections import Counter

lst = [2,3,0,3]

c = Counter(lst)
print([c[x] for x in range(max(lst)+1)])
# [1, 0, 1, 2]

An alternate way avoiding loops:

from collections import Counter

lst = [2,3,0,3]

c = dict.fromkeys(range(max(lst)+1), 0)
c.update(Counter(lst))

print(c.values())
# # [1, 0, 1, 2]
Austin
  • 25,759
  • 4
  • 25
  • 48
2

You could probably use the following code:

lst = [2,3,0,1,3]
#Get list unique values using set
set_lst = sorted(set(lst))
#For each unique element, use the count method
counts = [lst.count(i) for i in set_lst]

At first, we find out all the unique elements of the list, by using a set object, which stores unique elements only. Then we traverse through the list and use the count method to get the counts of each element, which are sorted in order.

1

Another solution with count:

l = [2, 3, 0, 3]

assert len(l) == max(l) + 1

[l.count(num) for num, _ in enumerate(l)]
# [1, 0, 1, 2]
Mykola Zotko
  • 15,583
  • 3
  • 71
  • 73
  • always fun to see other ideas, but because of the need for the assertion, i still favor Counter way, have an upvote – katiex7 Mar 03 '19 at 07:33
1

If you want to avoid for keyword at any price, then you might use map instead, following way:

a = [2,3,0,3]
out = list(map(lambda x:a.count(x), list(range(max(a)+1))))
print(out) #[1, 0, 1, 2]

This solution assumes that a contains solely non-negative integers and is not empty list.

Daweo
  • 31,313
  • 3
  • 12
  • 25