1

I have a list that looks like this:

[['State', 'Gas', 'Air', 'Food', 'Party'],
 ['Alabama', 4802982, 9, 213068.0, 52419.02],
 ['Alaska', 721523, 3, 31618.0, 663267.26],
 ['Arizona', 6412700, 11, 144393.0, 113998.3],
 ['Arkansas', 2926229, 6, 209159.0, 53178.62],
 ['California', 37341989, 55, 394608.0, 163695.57],
 ['Colorado', 5044930, 9, 184289.0, 104093.57],
 ['Connecticut', 3581628, 7, 45744.0, 5543.33],
 ['Delaware', 900877, 3, 13849.0, 2489.27],
 ['District of Columbia', 0, 3, 3418.0, 68.34],
 ['Florida', 18900773, 29, 271024.0, 65754.59],
 ['Georgia', 9727566, 16, 271920.0, 59424.77],
 ['Hawaii', 1366862, 4, 9662.0, 10930.98],
 ['Idaho', 1573499, 4, 98649.0, 83570.08],
 ['Illinois', 12864380, 20, 305872.0, 57914.38]]

I want to create a list called total, which contains the sum of the data elements in this order: sum of states’ gas, sum of states’ air, sum of states’ food, and sum of states’ party. Obviously avoiding the column name list at the top of the list and also the states' names. I have tried multiple things, but this is what I think is leading me in the right direction so far:

total = [sum(x) for x in statesData[x]]
RoiMinuit
  • 404
  • 4
  • 17

3 Answers3

3

One way using zip and next:

it = zip(*statesData[1:])
next(it) # Pop out the state names

["Total", *(sum(i) for i in it)]

Output:

['Total', 106165938, 179, 2197273.0, 1436348.0800000003] 
Chris
  • 29,127
  • 3
  • 28
  • 51
1

If it is possible to use numpy, this can be solved with one line of code

data = [['State', 'Gas', 'Air', 'Food', 'Party'],
 ['Alabama', 4802982, 9, 213068.0, 52419.02],
 ['Alaska', 721523, 3, 31618.0, 663267.26],
 ['Arizona', 6412700, 11, 144393.0, 113998.3],
 ['Arkansas', 2926229, 6, 209159.0, 53178.62],
 ['California', 37341989, 55, 394608.0, 163695.57],
 ['Colorado', 5044930, 9, 184289.0, 104093.57],
 ['Connecticut', 3581628, 7, 45744.0, 5543.33],
 ['Delaware', 900877, 3, 13849.0, 2489.27],
 ['District of Columbia', 0, 3, 3418.0, 68.34],
 ['Florida', 18900773, 29, 271024.0, 65754.59],
 ['Georgia', 9727566, 16, 271920.0, 59424.77],
 ['Hawaii', 1366862, 4, 9662.0, 10930.98],
 ['Idaho', 1573499, 4, 98649.0, 83570.08],
 ['Illinois', 12864380, 20, 305872.0, 57914.38]]

sum_states = np.sum(np.array(data)[1:,1:].T.astype(np.float16),axis=1)

To solve this problem with list-comprehension, transpose the list of lists with map(list,zip(*data)) will be a good idea

[sum(item[1:]) for item in list(map(list, zip(*data)))[1:]]
meTchaikovsky
  • 7,478
  • 2
  • 15
  • 34
1

Obviously avoiding the column name list at the top of the list and also the states' names.

So, get rid of those first:

numbers = [row[1:] for row in data[1:]]

sum of the data elements [columnwise]

So the first thing we need to do is transpose the data to swap columns and rows, and then we can sum each row.

transposed = # go check the other answer!
total_gas, total_air, total_food, total_party = [sum(column) for column in transposed]
# Alternate spelling:
# total_gas, total_air, total_food, total_party = map(sum, transposed)
# This works because our function only needs one argument, which is an element
# from the transposed list; and because we are unpacking the resulting `map`
# object right away.

But it seems like your general underlying question is really "how do I get my head around list comprehensions?". In which case, please see this reference.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • I tried "sums = [sum(row[i+1]) for row in statesData]" and got list index out of range. Can it possibly be fixed to do what I'm looking for? I would rather use a simple primitive approach first – RoiMinuit Nov 27 '20 at 05:35
  • Where is the `i` value supposed to be coming from? – Karl Knechtel Nov 27 '20 at 05:36
  • based on your answer, I get that that code will not work either. – RoiMinuit Nov 27 '20 at 05:44
  • 1
    You're close. You just need to supply an `i` value in an organized, meaningful way. Think: when you want to get the total gas amount, what should `i` be equal to? How about for the other results? Now, try to think of a way to convert that into iteration, and use an outer list comprehension to manage that. Of course, you also still need to ignore the first row of `statesData`. You can easily do that with just `statesData[1:]`, which you'll notice is a recurring thing in the advice you've been given so far. – Karl Knechtel Nov 27 '20 at 05:51
  • wait... I'm getting a ticklish feeling in my brain... should I have something like row[i][1] ? – RoiMinuit Nov 27 '20 at 05:57
  • 1
    No, you should stick with the `row[i+1]` that you have. Just that `i` *needs to have a value that makes sense*. Please *actually read and answer each of my questions in order*, and only then try to write code. – Karl Knechtel Nov 27 '20 at 06:00