Cole
Cole

Reputation: 2509

python create a set / dict / list and the sum of its values from a single list comprehension

I wonder if two list comprehensions are needed to return the ordered pair of a set / dict / list and the sum of the values in the set / dict / list. Here is an example of what I mean:

>>> l = ['abc', 'd', 'efgh', 'ij']
>>> {i: len(i) for i in l}, sum(len(i) for i in l)
({'efgh': 4, 'abc': 3, 'ij': 2, 'd': 1}, 10)

Is there a better / more pythonic way to write this than with duplicate for i in l comprehensions?

UPDATE:

I asked this question because I was thinking of the best way to write a particular lambda; i.e.

>>> l = ['abc', 'd', 'efgh', 'ij']
>>> dict_value = lambda l: ({i: len(i) for i in l}, sum(len(i) for i in l))
>>> dict_value(l)
({'efgh': 4, 'abc': 3, 'ij': 2, 'd': 1}, 10)

I asked this question because I am not using len() to calculate the value I want, but rather a expensive calculation. The point below about the for-loop does solve the problem if I define a secondary method rather than a lambda to do work.

Upvotes: 2

Views: 3463

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1124060

Yes, or you just use a regular loop:

d, s = {}, 0
for i in l:
    d[i] = len(i)
    s += len(i)

A list or set or dictionary comprehension should be used to create one object; avoid trying to create side effects too. And don't discount the utility of a regular loop!

Also, don't hesitate to use a function instead of a lambda:

def as_dict_and_total(l):
    d, s = {}, 0
    for i in l:
        d[i] = len(i)
        s += len(i)
    return d, s

Upvotes: 2

Hari Menon
Hari Menon

Reputation: 35445

You could precompute the lengths. I think it is cleaner to look at:

>>> l = ['abc', 'd', 'efgh', 'ij']
>>> llen = [len(i) for i in l]
>>> dict(zip(l,llen)), sum(llen)
({'abc': 3, 'd': 1, 'efgh': 4, 'ij': 2}, 10)

Upvotes: 3

Related Questions