0

I have the following an array of dictionaries:

dictionaty =[{'name': 'fire', 'command': '1;2;3;4'}, 
{'name': 'brain', 'command': '2;2;3;4'}, {'name': 'word', 'command': '1;3;4;5'},
{'name': 'cellphone', 'command': '6;1;3;4'}, {'name': 'ocean', 'command': '9;3;7;4'},

how do I get the dictionaries that have the command with the second and third value after ';' respectively equal? For example: 'command': '1;2;3;4' is equals 'command': '2;2;3;4'

guettli
  • 25,042
  • 81
  • 346
  • 663
carlaodev
  • 621
  • 2
  • 8
  • 18

2 Answers2

2

You can use itertools.groupby. You can construct a lambda expression that looks for the value corresponding to the 'command' key, then finds the [1] and [2] elements of splitting on the ';' character.

d =[{'name': 'fire', 'command': '1;2;3;4'},
    {'name': 'brain', 'command': '2;2;3;4'},
    {'name': 'word', 'command': '1;3;4;5'},
    {'name': 'cellphone', 'command': '6;1;3;4'},
    {'name': 'ocean', 'command': '9;3;7;4'}]

import itertools
groups = itertools.groupby(d, lambda i: i['command'].split(';')[1:3])

for key, group in groups:
    print(list(group))

Output

[{'name': 'fire', 'command': '1;2;3;4'}, {'name': 'brain', 'command': '2;2;3;4'}]
[{'name': 'word', 'command': '1;3;4;5'}]
[{'name': 'cellphone', 'command': '6;1;3;4'}]
[{'name': 'ocean', 'command': '9;3;7;4'}]

To find groups that had more than one member, you need one more step:

for key, group in groups:
    groupList = list(group)
    if len(groupList) > 1:
        print(groupList)

[{'command': '1;2;3;4', 'name': 'fire'}, {'command': '2;2;3;4', 'name': 'brain'}]
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • But the output is equal to the array in this case, I expect that only the lines were the result: {'name':'fire','command':'1;2;3;4'}, {'name': 'brain', 'command': '2;2;3;4'} – carlaodev Oct 17 '14 at 17:13
  • Sorry but, what is [1:3] on (d, lambda i: i['command'].split(';')[1:3])? – carlaodev Oct 17 '14 at 17:36
  • I'm taking the string `'1;2;3;4'` and splitting on the `';'`. This will return the list `['1','2','3','4']`. I am using [slice notation](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) To get the 2nd and 3rd element, which are at `[1]` and `[2]`. The slice `[1:3]` means `[start:stop]`, but it goes up to "stop" but doesn't include it. – Cory Kramer Oct 17 '14 at 17:38
0

You can iterate the items and for each item check the items to follow and compare the last part of 'command':

dictionaty =[{'name': 'fire', 'command': '1;2;3;4'}, 
             {'name': 'brain', 'command': '2;2;3;4'}, 
             {'name': 'word', 'command': '1;3;4;5'},
             {'name': 'cellphone', 'command': '6;1;3;4'}, 
             {'name': 'ocean', 'command': '9;3;7;4'}]

for i, itm in enumerate(dictionaty):
    itm_last_part = itm['command'].split(';')[2:]
    for second in dictionaty[i+1:]:
        second_last_part = second['command'].split(';')[2:]
        if itm_last_part == second_last_part:
            print itm, second, "are equal"

OUTPUT

{'command': '1;2;3;4', 'name': 'fire'} {'command': '2;2;3;4', 'name': 'brain'} are equal
{'command': '1;2;3;4', 'name': 'fire'} {'command': '6;1;3;4', 'name': 'cellphone'} are equal
{'command': '2;2;3;4', 'name': 'brain'} {'command': '6;1;3;4', 'name': 'cellphone'} are equal
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129