ZK Zhao
ZK Zhao

Reputation: 21573

Python & Pandas: Find a dict within a list according to a key's value

I have a list which look like this:

dict_list = [{'angle': 5.0,
              'basic_info': '111',
              'x': [1,2,3,4],
              'y': [3,2,1,4],},
            {'angle': 25.0,
              'basic_info': '111',
              'x': [1,2,3,4],
              'y': [3,1,5,2],},
            {'angle': 3.0,
              'basic_info': '111',
              'x': [1,2,3,4],
              'y': [1,1,4,1],},]

I want to get the dict angle 25, how can I do it?


UPDATE:

After playing a while with Pandas, I find this might be possible

df = pd.DataFrame(dict_list)
temp = df.query("(angle ==25 )").T.to_dict()[temp.keys()[0]]
temp

Returns

{'angle': 25.0, 'basic_info': '111', 'x': [1, 2, 3, 4], 'y': [3, 1, 5, 2]}

But this is a bit hack.

Upvotes: 2

Views: 81

Answers (2)

Kevin J. Chase
Kevin J. Chase

Reputation: 3956

The built-in filter function will do what you want... you just need to feed it a function that determines which objects to keep. That function below is has_angle.

I wrapped has_angle in filter_by_angle, so I could use functools.partial to avoid hard-coding the angle sought. filter_by_angle is a generator function, so it can yield any number of matching shapes.

import functools


def has_angle(angle, shape):
    # get with default None prevents a KeyError on shapes
    # without angles.
    return shape.get('angle', None) == angle


def filter_by_angle(angle, shapes):
    filter_key = functools.partial(has_angle, angle)
    yield from filter(filter_key, shapes)


def main():
    dict_list = ...  # Same as yours.
    matching_shapes = filter_by_angle(25, dict_list)
    for shape in matching_shapes:
        print(shape)
    return

This prints:

{'y': [3, 1, 5, 2], 'angle': 25.0, 'x': [1, 2, 3, 4], 'basic_info': '111'}

Note that the yield from syntax requires Python 3.3 or greater.

Upvotes: 0

Alexander
Alexander

Reputation: 109636

Assuming each angle in your dictionary is unique and each dictionary contains the key 'angle':

df = None
for sub_dict in dict_list:
    if sub_dict['angle'] == 25:
        df = pd.DataFrame({'x': sub_dict['x'], 'y': sub_dict['y']})
        break  # Stops after finding the first matching angle.
if df is not None:
    df.plot(x='x', y='y')

enter image description here

Upvotes: 2

Related Questions