1

I am very new to python and this forum :) I have been struggling with dictionary and can really use some help.

For my question, the Input is:

frontier = [
              { 'state': (2, 5, 4, 3, 0, 1), 'path': [ 'PULL' ] },
              { 'state': (2, 4, 5, 0, 3, 1), 'path': [ 'SWAP','PULL' ] },
              { 'state': (2, 5, 4, 0, 1, 3), 'path': [ 'SWAP' ] },
              { 'state': (2, 0, 5, 4, 3, 1), 'path': [ 'PUSH', 'PUSH' ] },

            ]

We are told that the assigned value of each action:

  • PUSH: 5
  • PULL: 6
  • SWAP: 8
  • FLIP: 2

    eg. if [ push, swap] = 5+8

For this question, every state has an assigned value (heuristic) that I have calculated.

However, calculating the value of actions has me stumped. I have tried coding by splitting the item['path'] but the list it creates cannot be used. I have no idea how to approach this.

I want to make a list for the action. For the above question, it will look:

[6, 14, 8, 10]

Can someone please tell me how it can be achieve with explanation and code for the given example?

Ajax1234
  • 69,937
  • 8
  • 61
  • 102
Alex Ham
  • 151
  • 1
  • 12
  • So basically the sum? – Anton vBR Apr 16 '18 at 21:43
  • The sum of the actions for any given state. The main problem I have is how to convert it to list and assign it value. – Alex Ham Apr 16 '18 at 21:45
  • Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation, as suggested when you created this account. [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) applies here. We cannot effectively help you until you post your MCVE code and accurately describe the problem. We should be able to paste your posted code into a text file and reproduce the problem you described. What you posted is not a problem specification. As given, you're simply asking us to write your code for you -- and without a proper description. – Prune Apr 16 '18 at 21:54
  • I apologise. My code was actually useless so I thought it was better to leave it out. The reason why I gave a description of it ( I have tried coding by splitting the item['path'] but the list it creates cannot be used.) I will keep it in mind next time – Alex Ham Apr 16 '18 at 21:58

5 Answers5

1

This is one way.

frontier = [{ 'state': (2, 5, 4, 3, 0, 1), 'path': [ 'PULL' ] },
            { 'state': (2, 4, 5, 0, 3, 1), 'path': [ 'SWAP','PULL' ] },
            { 'state': (2, 5, 4, 0, 1, 3), 'path': [ 'SWAP' ] },
            { 'state': (2, 0, 5, 4, 3, 1), 'path': [ 'PUSH', 'PUSH' ] }]

d = {'PUSH': 5, 'PULL': 6, 'SWAP': 8, 'FLIP': 2}

res = [sum(map(d.get, item['path'])) for item in frontier]

print(res)

[6, 14, 8, 10]

Explanation

  • Create a dictionary mapping actions to values.
  • Use sum with map to lazily calculate the the sum of all actions in a dictionary.
  • Use a list comprehension to loop through each dictionary in the list.
jpp
  • 159,742
  • 34
  • 281
  • 339
  • Thank you so much. Can you elaborate a bit on what 'map' does? – Alex Ham Apr 16 '18 at 21:54
  • Sure, `map` applies a function to *each value* in an iterable, and returns an iterable. The function in this case is `d.get`, i.e. get a value from the dictionary given key. The iterable is the items in `item[path]`. You find more about `map` [here](https://stackoverflow.com/questions/10973766/understanding-the-map-function). – jpp Apr 16 '18 at 22:04
1

Try this:

result = []
for item in frontier:
    item_path_value = 0
    for action in item['path']:
        item_path_value += action.value
    result.append(item_path_value)

where action.value should return the value for that specific action

leoschet
  • 1,697
  • 17
  • 33
0

Try this:

frontier = [
              { 'state': (2, 5, 4, 3, 0, 1), 'path': [ 'PULL' ] },
              { 'state': (2, 4, 5, 0, 3, 1), 'path': [ 'SWAP','PULL' ] },
              { 'state': (2, 5, 4, 0, 1, 3), 'path': [ 'SWAP' ] },
              { 'state': (2, 0, 5, 4, 3, 1), 'path': [ 'PUSH', 'PUSH' ] },

            ]

d = dict(PUSH=5, PULL=6, SWAP=8, FLIP=2)

out = [sum(d.get(i,0) for i in x['path']) for x in frontier]
print(out)

Returns:

[6, 14, 8, 10]

The .get(key, default) function is your friend here. It will fetch a value from a dictionary given a key and if not found returns the default value. We sum this for all items in the dictionary value path.

Anton vBR
  • 18,287
  • 5
  • 40
  • 46
0

If you are trying to find the total sum for each path, create a dictionary storing the values for each action:

frontier = [{'path': ['PULL'], 'state': (2, 5, 4, 3, 0, 1)}, {'path': ['SWAP', 'PULL'], 'state': (2, 4, 5, 0, 3, 1)}, {'path': ['SWAP'], 'state': (2, 5, 4, 0, 1, 3)}, {'path': ['PUSH', 'PUSH'], 'state': (2, 0, 5, 4, 3, 1)}]
actions = {'PUSH': 5, 'PULL': 6, 'SWAP': 8, 'FLIP': 2}
final_dict = [{**b, **{'path':sum(actions.get(i) for i in b['path'])}} for b in frontier]

Output:

[{'state': (2, 5, 4, 3, 0, 1), 'path': 6}, {'state': (2, 4, 5, 0, 3, 1), 'path': 14}, {'state': (2, 5, 4, 0, 1, 3), 'path': 8}, {'state': (2, 0, 5, 4, 3, 1), 'path': 10}]

For the condensed result:

print([i['path'] for i in final_dict])

Output:

[6, 14, 8, 10]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
0

You can simply try this approach:

frontier = [
              { 'state': (2, 5, 4, 3, 0, 1), 'path': [ 'PULL' ] },
              { 'state': (2, 4, 5, 0, 3, 1), 'path': [ 'SWAP','PULL' ] },
              { 'state': (2, 5, 4, 0, 1, 3), 'path': [ 'SWAP' ] },
              { 'state': (2, 0, 5, 4, 3, 1), 'path': [ 'PUSH', 'PUSH' ] },

            ]

data = {'PUSH': 5, 'PULL': 6, 'SWAP': 8, 'FLIP': 2}


for j,i in enumerate(frontier):
    actions=[]
    for k in i['path']:
        actions.append(data[k])

    frontier[j]['path']=sum(actions)

print(frontier)

output:

[{'state': (2, 5, 4, 3, 0, 1), 'path': 6}, {'state': (2, 4, 5, 0, 3, 1), 'path': 14}, {'state': (2, 5, 4, 0, 1, 3), 'path': 8}, {'state': (2, 0, 5, 4, 3, 1), 'path': 10}]
Aaditya Ura
  • 12,007
  • 7
  • 50
  • 88