user1243904
user1243904

Reputation: 13

how to access a nested comprehensioned-list

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

Answers (3)

pradyunsg
pradyunsg

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

BrenBarn
BrenBarn

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

sberry
sberry

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

Related Questions