Use enumerate:
In [3]: user_details = [{'name':x, 'rank':i} for i,x in enumerate(ranked_users)]
In [4]: user_details
Out[4]:
[{'name': 'jon', 'rank': 0},
{'name': 'bob', 'rank': 1},
{'name': 'jane', 'rank': 2},
{'name': 'alice', 'rank': 3},
{'name': 'chris', 'rank': 4}]
PS. My first answer was
user_details = map(lambda (i,x): {'name':x, 'rank':i}, enumerate(ranked_users))
I'd strongly recommend using a list comprehension or generator expression over map and lambda whenever possible. List comprehensions are more readable, and tend to be faster to boot.
Use enumerate:
In [3]: user_details = [{'name':x, 'rank':i} for i,x in enumerate(ranked_users)]
In [4]: user_details
Out[4]:
[{'name': 'jon', 'rank': 0},
{'name': 'bob', 'rank': 1},
{'name': 'jane', 'rank': 2},
{'name': 'alice', 'rank': 3},
{'name': 'chris', 'rank': 4}]
PS. My first answer was
user_details = map(lambda (i,x): {'name':x, 'rank':i}, enumerate(ranked_users))
I'd strongly recommend using a list comprehension or generator expression over map and lambda whenever possible. List comprehensions are more readable, and tend to be faster to boot.
Alternatively you could use a list comprehension rather than map() and lambda.
ranked_users = ['jon','bob','jane','alice','chris']
user_details = [{'name' : x, 'rank' : ranked_users.index(x)} for x in ranked_users]
Output:
[{'name': 'jon', 'rank': 0}, {'name': 'bob', 'rank': 1}, {'name': 'jane', 'rank': 2}, {'name': 'alice', 'rank': 3}, {'name': 'chris', 'rank': 4}]
List comprehensions are very powerful and are also faster than a combination of map and lambda.
python - Can I use index information inside the map function? - Stack Overflow
indexing - How to make an index static for a python lambda expression - Stack Overflow
[aws-lambda-python] Unify `entry` field betwen aws-lambda-nodejs and aws-lambda-python
"Unable to import module 'index': No module named 'index'"
Videos
You could do that in a one-liner using generators:
next(i for i,v in enumerate(l) if is_odd(v))
The nice thing about generators is that they only compute up to the requested amount. So requesting the first two indices is (almost) just as easy:
y = (i for i,v in enumerate(l) if is_odd(v))
x1 = next(y)
x2 = next(y)
Though, expect a StopIteration exception after the last index (that is how generators work). This is also convenient in your "take-first" approach, to know that no such value was found --- the list.index() function would raise ValueError here.
One possibility is the built-in enumerate function:
def index_of_first(lst, pred):
for i, v in enumerate(lst):
if pred(v):
return i
return None
It's typical to refer a function like the one you describe as a "predicate"; it returns true or false for some question. That's why I call it pred in my example.
I also think it would be better form to return None, since that's the real answer to the question. The caller can choose to explode on None, if required.
Use the enumerate() function to add indices:
map(function, enumerate(a))
Your function will be passed a tuple, with (index, value). In Python 2, you can specify that Python unpack the tuple for you in the function signature:
map(lambda (i, el): i * el, enumerate(a))
Note the (i, el) tuple in the lambda argument specification. You can do the same in a def statement:
def mapfunction((i, el)):
return i * el
map(mapfunction, enumerate(a))
To make way for other function signature features such as annotations, tuple unpacking in function arguments has been removed from Python 3.
Demo:
>>> a = [1, 3, 5, 6, 8]
>>> def mapfunction((i, el)):
... return i * el
...
>>> map(lambda (i, el): i * el, enumerate(a))
[0, 3, 10, 18, 32]
>>> map(mapfunction, enumerate(a))
[0, 3, 10, 18, 32]
You can use enumerate():
a = [1, 3, 5, 6, 8]
answer = map(lambda (idx, value): idx*value, enumerate(a))
print(answer)
Output
[0, 3, 10, 18, 32]
Python's closures are late binding. This means that the values of variables used in closures are looked up at the time the function is called.
To avoid the late binding effect you can use a lambda with a default arg:
index = 1
test = lambda t, index=index: t[index]+1 # binds index at definition time
index = 0
print(test([5, 0])) # 1
index is neither an argument nor a local variable in test() so it is indeed resolved as a a nonlocal (+> it's looked up in the enclosing scopes).
The simple solution is to make index an argument of test with a default value capturing the value of index at definition time:
index = 1
test = lambda t, _index=index: t[_index]+1
index = 0
print(test([5, 0]))
I’m dealing with simple terraform app with lambda function;
I got this error :
{
“errorMessage”: “Unable to import module ‘index’: No module named ‘index’”,
“errorType”: “Runtime.ImportModuleError”,
“stackTrace”:
}
this is the main.tf file
provider "aws" {
region = "us-east-1"
}
resource "aws_iam_role" "lambda_role" {
name = "Spacelift_Test_Lambda_Function_Role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy" "iam_policy_for_lambda" {
name = "aws_iam_policy_for_terraform_aws_lambda_role_1"
path = "/"
description = "AWS IAM Policy for managing aws lambda role"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role" {
role = aws_iam_role.lambda_role.name
policy_arn = aws_iam_policy.iam_policy_for_lambda.arn
}
data "archive_file" "zip_the_python_code" {
type = "zip"
source_dir = "${path.module}/python/"
output_path = "${path.module}/python/index.zip"
}
resource "aws_lambda_function" "terraform_lambda_func" {
filename = "${path.module}/python/index.zip"
function_name = "Spacelift_Test_Lambda_Function"
role = aws_iam_role.lambda_role.arn
handler = "index.lambda_handler"
runtime = "python3.8"
depends_on = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]
}the index.py file
def lambda_handler(event, context):
message = 'Hello {} !'.format(event['key1'])
return {
'message' : message
}I think this code is closer to what you are asking for:
def indexMatching(seq, condition):
for i,x in enumerate(seq):
if condition(x):
return i
return -1
class Z(object):
def __init__(self, name):
self.name = name
class X(object):
def __init__(self, zs):
self.mylist = list(zs)
def indexByName(self, name):
return indexMatching(self.mylist, lambda x: x.name==name)
x = X([Z('Fred'), Z('Barney'), Z('Wilma'), Z('Betty')])
print x.indexByName('Wilma')
Returns 2.
The key idea is to use enumerate to maintain an index value while iterating over the sequence. enumerate(seq) returns a series of (index,item) pairs. Then when you find a matching item, return the index.
If you really want to use a lambda, the syntax is:
lambda param, list: return_value
For example, this is a lamdba that does addition:
lambda x, y: x + y
I'm not sure how this could make your function easier to write though, since this is the most obvious way:
def myFunction(name):
for i, x in enumerate(self.getList()):
if x.name == name:
return i
Your lamdba would be this though:
lamdba x: x.name == name
So one horrible way of doing this is:
def myFunction(name):
matches = [index
for index, value in enumerate(self.getList())
if value.name == name]
if matches:
return matches[0]
You can pass the array as a parameter to the lambda, and access the elements inside the lambda using its indexes:
print map(lambda x: x[0]/(x[1]**2), [a])
Also, you're using the bitwise XOR operator (^), not the "power" operator (**)
But... I don't see the point of using a lambda here, you just want to do some calculation of those 2 elements. So you can just do:
print a[0]/a[1]**2
https://docs.python.org/2/library/functions.html#map
map(function, iterable, ...) Apply function to every item of iterable and return a list of the results...
a is iterable, because raw_input().split(' ') is iterable, but a[0] and a[1] are not.
You should just print a[0] / a[1]**2
Correct input
6
47 1.30
84 2.45
52 1.61
118 2.05
70 1.67
75 1.58
And code
for i in range(int(raw_input())):
a = map(float, raw_input().split(' '))
print a[0] / a[1]**2
