How to test each element in a list (with little more complex logic)?

126 views Asked by At

I have a list that is dynamically generated:

myList = [[node1, mask1],
          [node2, mask1], 
          [node3, mask1], 
          [node4, mask2], 
          [node5, mask2], 
          [node6, mask3],
          [node7, mask4],
         ]

Note: each node/mask in the list are actual Nodes in the software GUI, that I am trying to access and manipulate later. I think representing them as strings for now, would serve the purpose fine.

Rules:

  1. I must logically compare each item in the list with each other to get the result;
  2. keep all the nodes except those that have connection to only one type of mask, in this example, node6, and 7, needs to be excluded and get the following result:

    newList = [[node1, node2, node3], [node4, node5]]
    

Optional: I would also like to keep some information of each node to what mask has been connected so I can use that later - but I can think of other solutions to this so it's optional.

I tried looping through each element with nested for loops but that misses some cases. I also tried working with groupby(), but I can't figure it out, as my Python knowledge is limited.

1

There are 1 answers

5
tihom On BEST ANSWER

You can use a defaultdict to group all nodes with same mask into a list:

from collections import defaultdict

myList = [['node1', 'mask1'],
          ['node2', 'mask1'], 
          ['node3', 'mask1'], 
          ['node4', 'mask2'], 
          ['node5', 'mask2'], 
          ['node6', 'mask3'],
          ['node7', 'mask4'],
         ]

# create a hash with key as mask
# and value as list of nodes with that mask 
node_gps = defaultdict(list)
for item in myList:
    node = item[0]
    mask = item[1]
    node_gps[mask].append(node)

print node_gps
# =>  {'mask4': ['node7'], 
#      'mask1': ['node1', 'node2', 'node3'], 
#      'mask3': ['node6'], 
#      'mask2': ['node4', 'node5']}


# filter out nodes with only one match
# using list comprehension
newList =  [v for k, v in node_gps.items() if len(v) > 1]

# or using for loops
newList = []
# iterate over each mask, nodes pair in node_gps
for mask, nodes in node_gps.items():
    # append a node_list if it has more than 1 node
    if len(nodes) > 1:
        newList.append(nodes)

print newList
# [['node1', 'node2', 'node3'], 
#  ['node4', 'node5']]

The node_gps dict also stores the mask associated with each list of nodes.