Reputation: 13
I have a working solution for creating a list some of random numbers, count their occurrencies, and put the result in a dictionary which looks the following:
random_ints = [random.randint(0,4) for _ in range(6)]
dic = {x:random_ints.count(x) for x in set(random_ints)])
so that for, say [0,2,1,2,1,4] I get {0: 1, 1: 2, 2: 2, 4:1}
I was wondering if its possible to express this in a one liner, preferably without the use of a library function - I want to see what's possible with python :) When I try to integrate the two lines in one I dont know howto express the two references to the same comprehensioned list of random_ints ..??? I expected something like:
dic = {x:random_ints.count(x) for x in set([random.randint(0,4) for _ in range(6)] as random_ints))
which of course does not work...
I looked (nested) list comprehensions up here on SO, but I could not apply the solutions I found to my problem.
thanks, s.
Upvotes: 1
Views: 104
Reputation: 19486
Using as
in the list dict-comprehension won't work.
Try this:
dic = {x:random_ints.count(x)
for random_ints in ([random.randint(0,4) for _ in range(6)],)
for x in set(random_ints))
I think using collections.Counter
is a better idea:
>>> import collections, random
>>> c = collections.Counter(random.randint(0, 6) for _ in range(6))
>>> c
Counter({6: 3, 0: 1, 3: 1, 4: 1})
Upvotes: 1
Reputation: 251578
There are a couple ways to achieve something like that, but none of them is exactly what you want. What you can't do is simple binding of a name to a fixed value inside the list/dict comprehension. If random_ints
does not depend on any of the iteration variables needed for dic
, it's better to do it the way you did it, and create random_ints
separately.
Conceptually, the only things that should be in the dict comprehension are the things that need to be created separately for each item in the dict. random_ints
doesn't meet this criterion; you only need one random_ints
overall, so there's no reason to put it in the dict comprehension.
That said, one way to do it is to fake it by iterating over a one-element list containing your random_ints
:
{x:random_ints.count(x) for random_ints in [[random.randint(0,4) for _ in range(6)]] for x in set(random_ints)}
Upvotes: 2
Reputation: 132138
Here is a one-liner that relies on random
and collections
modules.
>>> import collections
>>> import random
>>> c = collections.Counter(random.randint(0, 6) for _ in range(100))
>>> c
Counter({2: 17, 1: 16, 0: 14, 3: 14, 4: 14, 5: 13, 6: 12})
Upvotes: 2