简体   繁体   中英

Python dictionary from list of lists

I am trying to generate a dictionary to count items in a list of lists with conditions. I am trying to get the results as values in a tuple, for example if my initial data is a list of lists like this:

my_list = [[(1,2),5],[(1,2),9],[(2,3),0],[(2,3),2],[(1,2),5],[(1,2),9],[(2,3),5]]

The desired outcome would be a dictionary with key the first element of each lists. The values of the dictionary would be a tuple of two elements, the number of items having that same key (total count) and how many values are 5 for the second item (conditional count).

dict_desired = {(1,2):(4,2),(2,3):(3,1)}

I did it but in a way that seems not very neat, and i was wondering if someone with more python experience could help me out to build it maybe using comprehensions.

Thanks in advance!

The pythonic, efficient way to do this is to use a loop:

my_list = [[(1,2),5],[(1,2),9],[(2,3),0],[(2,3),2],[(1,2),5],[(1,2),9],[(2,3),5]]
result = {}
empty = 0, 0

for key, value in my_list:
    count, fives = result.get(key, empty)
    result[key] = (count + 1, fives + (value == 5))

To do this using comprehensions, you require going over the list on each iteration, something like:

result = {
    key:(
        sum(k == key for k,_ in my_list),
        sum(v == 5 for k,v in my_list if k == key)
    ) for key, value in my_list
}

Which is very unpythonic and inefficient. You can maybe try to make a set out of the keys first, but it still won't be as efficient as the regular for-loop, and perhaps there is some hacky way with assignment expressions to make it work efficiently, but it certainly won't be neater .

So, you have a nice, readable, linear-time for-loop versus a convoluted, unreadable, quadratic time dictionary comprehension. The choice is clear, IMO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM