user2678074
user2678074

Reputation: 825

For loop over dictionary in Robot Framework

Is there a proper way to loop over a dictionary in RF? I used pythonic way, but failed:

:FOR  ${key}  ${value}  IN  &{dict}

output: Number of FOR loop values should be multiple of its variables. Got 2 variables but 1 value.

Same, when i pointed dictionary as scalar variable. I couldn't find an example in documentation though. Has anyone solved that?

P.S.

I am aware of workaround solution, that you use kw. Get Dictionary Keys and Get Dictionary Values, then, to update values you use Set To Dictionary ${key} ${new_value}, but this seems to be human unfriendly and uses several for loops iterations instead one.

Upvotes: 13

Views: 78316

Answers (9)

Johnrey San Miguel
Johnrey San Miguel

Reputation: 1

This will do that trick without loop in today’s version of Robot Framework

&{dict}=  Create dictionary key1=aaa     key2=bbb
&{updates}=  Create dictionary key1=xxx key2=zzz

Set to Dictionary    ${dict}    &{updates}
Should Be Equal   ${dict}[key1]   xxx
Should Be Equal   ${dict}[key2]   zzz

Upvotes: 0

Joost
Joost

Reputation: 21

FOR    ${key}    ${value}    IN    &{dictionary}
    Log To Console   key = ${key}, value = ${value}
END

This works fine in RF 3.2.2

Upvotes: 2

M H
M H

Reputation: 43

This works too:

FOR  ${key}  IN  @{res.keys()}
      Log    ${key}    
END

Upvotes: 0

Zane
Zane

Reputation: 926

I find this version more readable (with RF 3.2+)

FOR    ${key}    IN    @{mydict.items()}
    Log To Console    ${key}: ${mydict}[${key}]
END

Upvotes: 0

Dmitry O.
Dmitry O.

Reputation: 11

Try this (RF: 3.2.+):

FOR    ${key_value}    IN    @{mydict.items()}
        ${key}=  set variable  ${key_value}[0]
        ${value}=  set variable  ${key_value}[1]
        log  Key: ${key}; Value: ${value}
 END

Upvotes: 1

Todor Minakov
Todor Minakov

Reputation: 20067

To iterate over a dictionary's keys, you don't have to use any python method at all, but insted use the Robotframework's @ modifier for list expansion. For example:

${mydict}    Create Dictionary    a=1    b=2
:FOR    ${key}    IN    @{mydict}
\    Log     The current key is: ${key}
# there are at least to ways to get the value for that key
# "Extended variable syntax", e.g. direct access:
\    Log     The value is: ${mydict['${key}']}
# or using a keyword from the Collections library:
\    ${value}=    Get From Dictionary    ${mydict}    ${key}
\    Log     The value through Collections is: ${value}

The loop over the keys works straightaway, because in python a list() cast of a dictionary is actually the list of its keys. Sample code:

mydict = {'a': 1, 'b': 2}
print(list(mydict))
# the output is 
# ['a', 'b']

There is a python's dict method items() that iterates over the dictionary and returns a tuple of key, value. Regretfully, there is no direct substitute in Robot Framework's for loops, yet - this can be done with the Get Dictionary Items keyword. It returns a one-dimensional list, in the form

['key1', value_of_key1, 'key2', value_of_key2,]

Combining that with the @ list expansion, you can get both the key and the value in each cycle:

${mydict}    Create Dictionary      a=1    b=2
${items}     Get Dictionary Items   ${mydict}

:FOR    ${key}    ${value}    IN    @{items}
\    Log     The current key is: ${key}
\    Log     The value is: ${value}

Upvotes: 10

Viacheslav Tkach
Viacheslav Tkach

Reputation: 31

check solutions:

:FOR    ${key}    IN    @{mydict}
# works as @{mydict.keys()}

:FOR    ${key}    ${value}    IN    @{mydict.items()}
# doesn't work at all

Found another solutions which works:

:FOR    ${key}     ${value}    IN ZIP    ${mydict.keys()}    ${mydict.values()}

# And another less readable (can work without setters)
:FOR    ${el}    IN    @{mydict.items()}   
\    ${key}=    Set Variable    ${el[0]}
\    ${value}=    Set Variable    ${el[1]}

Upvotes: 3

chmc
chmc

Reputation: 265

Another workaround is to use the keyword "Get From Dictionary" during the for loop.

Loop through and Log key and value in dict
    [Documentation]    Loops through each key and stores the key value 
    ...                in a variable that can be used during the for 
    ...                loop, as if you were iterating through python 
    ...                with "for key, value in dict.iteritems()".
    &{mydict}    Create Dictionary    a=1    b=2
    :FOR    ${key}    IN    @{mydict.keys()}
    \    ${value}=    Get From Dictionary    ${mydict}    ${key}
    \    Log    ${key}, ${value}

reference: http://robotframework.org/robotframework/latest/libraries/Collections.html#Get%20From%20Dictionary

Upvotes: 4

Jan Kovařík
Jan Kovařík

Reputation: 1582

Loop Through Dict
    &{mydict}    Create Dictionary    a=1    b=2
    :FOR    ${key}    IN    @{mydict.keys()}
    \    Log    ${mydict["${key}"]}

Loop Through Dict And Multiplicate Values
    &{mydict}    Create Dictionary    a=1    b=2
    :FOR    ${key}    IN    @{mydict.keys()}
    \    ${new_value}    Evaluate    ${mydict["${key}"]}*2
    \    Set To Dictionary   ${mydict}    ${key}=${new_value}
    Log    ${mydict}

Upvotes: 24

Related Questions