How do I qualify that "data_point" is not more than the lengh of "sub_list"?

I well aware that I can get len(unsorted_list) for the number of sub lists. The data_point can’t be larger than the data_points in the sub list. I’m looking at keeping out errors due to data_point set to large. The variable data_point could be set in other parts of code. Am being overly concerned about possible bugs or any programer using this lambda is responsible for understanding it and staying with in it’s limits? I am aware of this, so it is not a problem at this time.

from operator import itemgetter

unsorted_list = [20, 1, 20, 40, 1, 0, 0, 0, 0, 0, 0, 0],[5, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],[9, 1, 20, 40, 1, 0, 0, 0, 0, 0, 0, 0]
data_point = 0
result = sorted(unsorted_list, key=itemgetter(data_point))
print('result ', result)

OUTPUT:

result  [[5, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0], [9, 1, 20, 40, 1, 0, 0, 0, 0, 0, 0, 0], [20, 1, 20, 40, 1, 0, 0, 0, 0, 0, 0, 0]]

I wish there was a good tutorial about lambda functions.
Thanks.

The code you show us doesn’t use any lambda functions.

Lambda functions are the same as regular def functions, with two important differences:

  • The body of the lambda can only contain a single expression, not a series of separate lines of code;

  • Lambdas are themselves an expression, so you can include them directly in another expression (unlike def functions which have to be created stand-alone first).

So I don’t think that lambdas are relevent here.

What exactly are you concerned about? Are you worried about the index data_point (which is a terrible name, since it is not a data point, it is an index) being out of range of the size of the sub lists?

If you set data_point too large, you will get an exception. Try it and see: set data_point = 1000000000 and see what happens.

As far as I understood the problem is as follows: “how to set limit for index value so that it will not exceed length of any sublist”. For that particular problem one can use length as key to built-in min function. This will return the shortest list. Having length of this shortest list will be the limit. Something like this:

>>> data = [20, 1, 20, 40, 1, 0, 0, 0, 0, 0, 0, 0],[5, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],[9, 1, 20, 40, 1, 0, 0, 0, 0, 0, 0, 0]
>>> len(min(data, key=len))
12

Yes. Thanks for the answer to a newbee. I knew that I needed to limit the chance of an error. It’s so helpful.

“I wish there was a good tutorial about lambda functions.”, I was hopeing someone knew off a good tutorial or book on the subject. It’s something that I think I need to learn yet.

Thanks again.

“I wish there was a good tutorial about lambda functions.”, I was
hopeing someone knew off a good tutorial or book on the subject. It’s
something that I think I need to learn yet.

There’s not much to learn.

This is a normal function definition:

 def square(x):
     return x * x

Here’s that written as a lambda:

 square = lambda x: x * x

There’s 2 things to notice here:

  • the lambda itself doesn’t have a name; we assign it to square
  • the lambda can only have a single expression in it

You can’t put control flow like loops or if-statements in a lambda.
They’re more for definining a functional expression to pass around. A
common use is the key function for a sort:

 >>> names = "Leonard", "Cameron", "jake"
 >>> names
 ('Leonard', 'Cameron', 'jake')
 >>> sorted(names)
 ['Cameron', 'Leonard', 'jake']
 >>> sorted(names, key=lambda name: name.lower())
 ['Cameron', 'jake', 'Leonard']

Here’s we’ve passed an ad hoc expression (name.lower()) as the
function to run to produce the value used for comparing things, where
the variable name is the function paramaeter in the lambda. We could
have gone:

 def sort_by_lowercase(name):
     return name.lower()

 print(sorted(names, key=sort_by_lowercase)

but that’s pretty wordy.

Lambda are almost always for fairly simple expressions you want to write
“right here”.

Here’s another example. I’ve got some code which makes numpy
datetime64 objects from UNIX times (seconds since 1970), and
datetime64s come in a few flavours - more precision (fractions of a
second) or more range (being able to express wider time periods by
having less precision). For my case I wanted a conversion function which
took a time suffix like 'ms' for milliseconds and and produces the
appropriate int containing the units for the datetime64:

 DT64_FROM_SECONDS = {
     's': int,
     'ms': lambda f: int(f * 1000),
     'us': lambda f: int(f * 1000000),
     'ns': lambda f: int(f * 1000000000),
 }

That’d be pretty wordy written using defs.

My function which uses that is here:

 def as_datetime64s(times, unit='s', utcoffset=0):
   ''' Return a Numpy array of `datetime64` values
       computed from an iterable of `int`/`float` UNIX timestamp values.

       The optional `unit` parameter (default `'s'`) may be one of:
       - `'s'`: seconds
       - `'ms'`: milliseconds
       - `'us'`: microseconds
       - `'ns'`: nanoseconds
       and represents the precision to preserve in the source time
       when converting to a `datetime64`.
       Less precision gives greater time range.
   '''
   # select scaling function
   try:
     scale = DT64_FROM_SECONDS[unit]
   except KeyError:
     # pylint: disable=raise-missing-from
     raise ValueError("as_datetime64s: unhandled unit %r" % (unit,))
   # apply optional utcoffset shift
   if utcoffset != 0:
     times = [t + utcoffset for t in times]
   return np.array([scale(t) for t in times]).astype(f'datetime64[{unit}]')

If you ignore the utcoffset (which is a gimmick for drawing some
plots) we look up the scale function:

 scale = DT64_FROM_SECONDS[unit]

and use it to make an array of datetime64 objects:

 np.array([scale(t) for t in times]).astype(f'datetime64[{unit}]')

So scale is a function!

Cheers,
Cameron Simpson cs@cskk.id.au

In addition to Camerons excellent answer: lambdas are useful in places where callable is required. For example keys in built-in sorted, min, max, map.

For example if there is list of names in form of first name, surname then sorting by surname can be done using lambda:

>>> names = 'Jane Smith', 'John Doe'
>>> sorted(names, key=lambda n: n.split()[-1])
['John Doe', 'Jane Smith']

One must be careful because sometimes built-in can be used instead of writing lambda. Lowercasing string can be done directly:

>>> names = "Leonard", "Cameron", "jake"
>>> sorted(names, key=str.lower)
['Cameron', 'jake', 'Leonard']