Home > Blockchain >  How to iterate through a list with a value from a dictionary
How to iterate through a list with a value from a dictionary

Time:10-23

I have a list with different values and a dictionary with different equations. I want to iterate with a for-loop through the list values and calculate a given equation. The example is below:

list = [1,2,3,4,5]
d ={"equation1": 2*x 3,
    "equation2": 3 4*x}

for x in list:
    y= d["equation1"]
    print(y)

the output is as you can see below:

5
5
5
5
5

When I put the dictionary into the forloop like the sample below, the right values are calculated:

list = [1,2,3,4,5]


for x in list:
    d ={"equation1": 2*x 3,
        "equation2": 3 4*x}
    
    y= d["equation1"]
    print(y)

Result:

5
7
9
11
13

How can I realise the right results with the dictionary outside the for-loop?

CodePudding user response:

In your first example:

list = [1,2,3,4,5]
d ={"equation1": 2*x 3,
    "equation2": 3 4*x}

This can only work if you somehow defined x previously, so you probably didn't share all of your relevant code.

Something like 2*x 3 gets evaluated immediately, so if x == 1, you'd get the result 5, as you suggest you do.

You could create a dict with lambda expressions:

d ={"equation1": lambda x: 2*x 3,
    "equation2": lambda x: 3 4*x}

But I wouldn't recommend it as good code. If you do though, this works:

list = [1,2,3,4,5]
d ={"equation1": lambda x: 2*x 3,
    "equation2": lambda x: 3 4*x}

for x in list:
    y = d["equation1"](x)
    print(y)

Note how on the line y = d["equation1"](x) x gets passed to the function accessed with d["equation1"] - a lambda expression is a simple function and the ones defined in the dict expect a single parameter.

A more appropriate solution would be:

def equation1(x):
    return 2*x 3


def equation2(x):
    return 3 4*x


xs = [1,2,3,4,5]
for x in xs:
    y = equation1(x)
    print(y)

And then if you have reason to refer to your functions with a dict from somewhere:

xs = [1,2,3,4,5]
funs = {
    'equation1': equation1,
    'equation2': equation2
}
for x in xs:
    y = funs['equation1'](x)
    print(y)

CodePudding user response:

The problem you have is that the expressions 2*x 3 and 3 4*x aren't something you can store in a dictionary. Rather, they get computed immediately, with whatever value of x is available when the dictionary is created. They do not use the value of x when the value gets looked up later.

If you want to store some code, like those expressions, to be run later, the natural way to do it in Python is using a function. The lambda keyword even lets you create functions that only evaluate a single expression, which is exactly what you want.

Try:

d = {"equation1": lambda: 2*x 3,
     "equation2": lambda: 3 4*x}

for x in list:
    d ={"equation1": 2*x 3,
        "equation2": 3 4*x}
    
    y = d["equation1"]() # note, here we're calling the lambda function
    print(y)

A few other notes:

It might make sense to use a different container than a dictionary for d, since your equation names don't appear to have a great deal of meaning. If you just want to index them by integer (e.g. 1 instead of "equation1"), a list is a much more natural choice.

Also, your equations currently pick the x value freely out of the enclosing namespace. It might be cleaner to pass in the x value as an argument to the lambda function. Grismar's very nice answer covers how to do this for x, so I won't give any redundant example code. Passing the values the equation needs as arguments does require a stricter "contract" to be established between the calling code and the equations though, as if one equation expects there to be a y or z variable defined, you need to know to pass it in as an argument.

  • Related