0

I am somehow stuck and would appreciate some helpful pointers.

I do not know in advance the length of the list [X]; i.e. the number of sub lists [y1,y2,y3,...,yn].

How can I work on each element from each sub list as function of the position?

That is,

Z1= avg(y1[1] + y2[1] + ,...., + y[1]n)

Z2= avg(y1[2] + y2[2] + ,...., + y[2]n)

Z3 = avg(y1[3] + y2[3] + ,...., + y[3]n)

.

.

.

Zm = avg(y1[m] + y2[m] + ,...., + y[m]n)

Any input is greatly appreciated,

Markus

Markus
  • 39
  • 5

1 Answers1

1

Assuming all the sublists have the same length, you can use zip to do this easily:

ally = [...]
averages = [sum(suby) / len(suby) for suby in zip(*ally)]

zip(*ally) effectively converts [[a1, a2, ...], [b1, b2, ...]] to tuples of (a1, b1), (a2, b2), etc., so Python does the work of matching up the values from each of the sublists for you.

If you want to handle the case where the lengths of the sublists don't match (e.g. [[a1, a2], [b1, b2, b3]]), it would be more complicated; you'd need to use itertools.zip_longest (izip_longest on Python 2) and filter out the junk entries to avoid including them in the average:

from itertools import zip_longest

# zip_longest matches up values until last value exhausted
# with shorter sequences substituting in None
# We then use the generator expression to remove the Nones
stripped = ([y for y in suby if y is not None] for suby in zip_longest(*ally))
# Then average as normal
averages = [sum(suby) / len(suby) for suby in stripped]

If you want to treat too short sub-lists as 0 (so they'll reduce the average), it's simpler:

averages = [sum(suby) / len(suby) for suby in zip_longest(*ally, fillvalue=0)]

where fillvalue can be changed to some other default value as desired.

Note: If this is Python 2 code, sum(suby) / len(suby) will be use truncating division if all the values are int/long; if you want true division, either add from __future__ import division to the top of the file (or run it in your interpreter) to get Py3 true division by default (use // for floor division), or wrap the len(suby) in a float() constructor (or multiply it by 1.0, whatever you like) so you don't drop the remainder on the floor.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271