Check and return dictionary items based on given key-value pairs

18 views
Skip to first unread message

kiteh

unread,
Apr 30, 2019, 5:16:14 PM4/30/19
to Python Programming for Autodesk Maya
Hi all, 

I am trying to do a 'skimming' or reduction method in dictionaries in which it will returns me a set of results from a given set of condition.

However my current method is more of an additive where it will simply lists me any items that fulfills any one of the condition.


Currently while it seems to be not working if there is only one key and one list item..


# Give me items that are menuA/a100 + menuB/b100, or menuA/a100 + menuB/b200
conditions = {'menuA':['a200']}

my_items = [
    {'item01' : {'menuA': ['a100'], 'menuB': ['b200']}},
    {'item02' : {'menuA': ['a200'], 'menuB': ['b200'], 'menuC' : ['c100']}},
    {'item03' : {'menuA': ['a100'], 'menuB': ['b200']}},
    {'item04' : {'menuA': ['a100', 'a200']}},
    {'item05' : {'menuB': ['b100'], 'menuC': ['c100']}}
]

result = []

for m in my_items:
   for mk, mv in m.items():
      all_conditions_met = len(conditions) == len(mv) #False
      for condition in conditions:
         if condition in mv:
            all_conditions_met &= bool((set(mv[condition]) & set(conditions[condition])))

            ###############
            # Tried the following but it will fail if given condition
            # eg. conditions = {'menuA': ['a100', 'a200'], 'menuB': ['b200']}
            # where it should return me ['item01', 'item03'] but it gives me [] instead...

            # all_conditions_met &= bool((set(mv[condition]) & set(conditions[condition]))) & (len(mv[condition]) == len(conditions[condition]))
            ###############

         else:
            all_conditions_met = False
            break
      if all_conditions_met:
         result.append(mk)

print result # 'item04'


In my above example, given the condition {'menuA':['a200']}, it should not be returning me any results as there are no items that consists only of {'menuA':['a200']} but yet it return me an item - closest to the given condition…


The idea behind this is to simply returns me items based on the conditions.


Could someone kindly share some insights on this matter?

Justin Israel

unread,
Apr 30, 2019, 5:49:48 PM4/30/19
to python_in...@googlegroups.com
First I would like to try and get clarification on exactly what you intend your conditions to mean. Given:

    conditions = {'menuA': ['a100', 'a200'], 'menuB': ['b200']}

I can assume from your example that an item must contain all keys of the condition. 
But for the values of each condition, is the item supports to contain all of the condition values, or just any of the condition values. This will determine what kind of testing you really need to be doing.

Can you also explain what your goal is between the outcome of your two variations:

    all_conditions_met &= bool((set(mv[condition]) & set(conditions[condition])))

and

    all_conditions_met &= bool((set(mv[condition]) & set(conditions[condition]))) \
        & (len(mv[condition]) == len(conditions[condition]))
 
The first variation does perform the "has ANY of the condition values" check, while the second is performing a "has ALL of the condition values" check. The second is also basically equivalent to doing the shorter:

    set(mv[condition] == set(conditions[condition])

Where are you actually stuck, between those two variations of the condition test?

- Justin

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/3eac4a92-ce87-4264-ad5a-e919aeef59a7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

kiteh

unread,
May 2, 2019, 1:39:53 PM5/2/19
to Python Programming for Autodesk Maya
Hi Justin, sorry for the delay in response.

It appears that I have gotten myself in this requirement that I am trying to achieve and in the end I manage to get it with the following code:

result = []
for item in my_items:
    k, v = list(item.items())[0]
    if all(any(x in v.get(kc, []) for x in vc) for kc, vc in conditions.items()):
        result.append(k)




Reply all
Reply to author
Forward
0 new messages