1

I'm not too sure how to ask this, and I'm not all that experienced with programming, so you'll have to forgive me. Anyways, I have an issue. Basically, I need to come up with the sum of some numbers and also the average.

The program is supposed to have the user inputs values. They input a month and a number associated with that month, and then I need to get the average. So I have one big list, and then lists within that list. It basically looks like this:

    months = [["January", 3.45], ["February", 7.1865], ["March", 4.56]]

What I'm wondering is, how do I single out the second element in each list? I was thinking that I could use a for loop and compiling the numbers into a separate list, but I tried that and I couldn't it to calculate correctly.

0

6 Answers 6

6

Might as well make this an answer and not a comment. The zip function works kind of like a zipper, combining matching elements:

>>> zip([1,2,3],[4,5,6])
<zip object at 0xb6e5beec>
>>> list(zip([1,2,3],[4,5,6]))
[(1, 4), (2, 5), (3, 6)]

and with the * operator, which basically turns f(*[a,b]) into f(a,b), we can go backwards:

>>> list(zip(*(zip([1,2,3],[4,5,6]))))
[(1, 2, 3), (4, 5, 6)]

So we can use zip to break apart your lists:

>>> list(zip(*months))
[('January', 'February', 'March'), (3.45, 7.1865, 4.56)]
>>> monthnames, numbers = zip(*months)
>>> monthnames
('January', 'February', 'March')
>>> numbers
(3.45, 7.1865, 4.56)

This is a little less efficient if you only care about one of them, but is a useful idiom to be familiar with.

Sign up to request clarification or add additional context in comments.

2 Comments

Clever. I wouldn't have thought of zip for this one.
Might want to make a comment that on py2k, zip(*months) returns a list whereas on py3k, it's an iterator "zip object".
6

Nobody's said this one yet:

sum(x[1] for x in monthlist)

As mentioned in the comments below, if you know each element in the monthlist is iterable and has exactly 2 elements, you can make this a little more explicit by unpacking the tuples as you go:

sum(value for month,value in monthlist)

This doesn't create an intermediate list just to pass to sum. That's the beauty of generators. The real beauty here is if monthlist were some sort of lazy iterator (e.g. a file object). Then you could sum over it without storing more than one element in memory at a time:

#code to sum the first column from a file:
with open(file) as f:
    first_col_sum = sum(float(line.split()[0]) for line in f)

2 Comments

I like the named version too: sum(num for name, num in monthlist), although it hardcodes the structure more than x[1].
@DSM -- Added that version as well (thanks). Usually in that case I'd use sum(num for _,num in monthlist), but now I'm starting to rethink that. After all, why not give myself a reminder about what monthlist actually stores?
5

List comprehensions can help you here:

names = [item[0] for item in months]
numbers = [item[1] for item in months]

If you're using just plain for loops, things get much messier:

names = []
numbers = []

for item in months:
    names.append(item[0])
    numbers.append(item[1])

Comments

3

To extract the second element in each list:

numbers = [i[1] for i in months]

If you want to get the sum of all the numbers:

numbersum = sum(numbers)

Comments

1

One more option with itemgetter:

from operator import itemgetter

months = [["January", 3.45], ["February", 7.1865], ["March", 4.56]]
sum(map(itemgetter(1), months)) # what means sum all items where each item is retrieved from month using index 1

Comments

0

Adding because I don't see it already.

>>> map(None,*months)
[('January', 'February', 'March'), (3.4500000000000002, 7.1864999999999997, 4.5599999999999996)]

So map(None, *months)[1] is the list you seek.

2 Comments

This is because map(None, *x) is the same as zip(*x).
I don't think this will actually work in Python 3. list(map(None, *months)) gives TypeError: 'NoneType' object is not callable; I think they removed the None shortcut.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.