1

I have a data structure:

my_list = [0] {key1: [1, 2, 3]
               key2: [4, 5, 6]
               key3: .....
               key4: .....}

          [1] {key1: [.......]
               key2: [... etc.

That is, a list of 4 dictionaries, each dictionary having 4 keys and each key a list of 3 values. Nice and consistent.

I want to loop through each value in each list and update it with an external function. This external function takes 2 arguments (the value I'm updating and the float value contained in its respective key). It's a basic bit of math but the problem is in iterating through the files as it is getting complex and I'm getting lost.

What I have done so far:

def Efunction_conversion(my_list):
    converted_dict_list = []
    for i in range(0,4):
        new_dict = {key:[external_function(float(key), value) for key, value in my_list[i].iteritems()]} ##problems occur here
        converted_dict_list.append(new_dict)
    return converted_dict_list

The code is not working and it may be obvious to others why.

The external function:

def external~_function(key, value):
    E = ((value - key)/key)**2
    return E

And the error, TypeError: unsupported operand type(s) for -: 'list' and 'float'

So the line main iteration line is passing a list instead of each element it seems.

The6thSense
  • 8,103
  • 8
  • 31
  • 65
cc6g11
  • 477
  • 2
  • 10
  • 24

3 Answers3

2

Inside your for loop, you are creating the dict with only a single key, and the looping over of the keys is happening only for the list comprehension -

[external_function(float(key), value) for key, value in my_list[i].iteritems()]

It is not happening for the dict as such. also, If I am not wrong, value is a list, so you are passing the whole list as parameter to the external function, which may not be what you want.

A simple way to do this would be (for Python 2.7+ with dictionary comprehension) -

def Efunction_conversion(my_list):
    converted_dict_list = []
    for x in my_list:
         converted_dict_list.append({key:[external_function(float(key),y) for y in value] for key, value in x.iteritems()}
    return converted_dict_list

A one liner for this would be -

def Efunction_conversion(my_list):
    return [{key:[external_function(float(key),y) for y in value] for key, value in x.iteritems()} for x in my_list]
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
  • This looks good I'll check this thanks you.! As a quick question, what does the key: syntax do? I've never come across that or know what its called. – cc6g11 Jul 14 '15 at 09:06
  • 1
    That is dictionary comprehension . Check it out here - http://stackoverflow.com/questions/14507591/python-dictionary-comprehension – Anand S Kumar Jul 14 '15 at 09:10
1

The problem is with your external function you could change it to this:

def external_function(key, value): 
    E=0.0
    for v in value:
        E += ((v- key)/key)**2 
    return E

If you want it as a list:

def external_function(key, value): 
    E=[]
    for v in value:
        E.append( ((v- key)/key)**2 )
    return E

your external_function required a float/int but it got a list so the error was thrown

The6thSense
  • 8,103
  • 8
  • 31
  • 65
1

If you are having a trouble writing/understanding a list/dict comprehension, indent it first before trying to write a one-liner:

my_list = [
    {'key1': [1, 2, 3],
     'key2': [4, 5, 6],}
]

def external_function(key, value):
    return key + str(value)

other_list = [
    {
        k: [external_function(k, el) for el in v]
        for k, v in d.iteritems()
    }
    for d in my_list
]

[{'key1': ['key11', 'key12', 'key13'], 'key2': ['key24', 'key25', 'key26']}]
Maciej Gol
  • 15,394
  • 4
  • 33
  • 51