简体   繁体   中英

List of dicts each with different keys, best way to look for a sequence of dicts

I have a list of dicts (list with each entry being a dict). Each dict has a different set of keys, so one dict may have a key that is not present with the other dicts in the list. I am trying to find a specific order of dicts inside this list. Basically, the list is from a wireshark capture and I want to look for certain packets. There is a specific sequence of packets in the middle of the list. Also, inside this sequence, there are some packets which I wish to ignore/filter. What is the best way to achieve this? I have some pseudo code written below:

for i in range(len(packets)):
    p = packets[i].fields # This method turns the packet object into a dict
    try:
        if p['some_field'] == A_CONSTANT_I_HAVE_DEFINED:
            # Mark this packet as part of the sequence
            # Save as part of sequence
            first_packet = p
            # Do not check for this condition again! I want to go to the next
            # iteration once I come across a packet with similar property
            # (the equality satisfied)
        if p['some_field'] == ANOTHER_CONSTANT:
            # Same as above
            second_packet = p
        if p['some_other_field'] == SOME_OTHER_CONSTANT:
            # Same as above
            third_packet = p
     except KeyError as err:
         pass

# Now I should have first_packet, second_packet and third_packet
# The list packets will always have the sequence of packets I am looking for

Note how I have the fields some_field and some_other_field different, and the different constants: A_CONSTANT_I_HAVE_DEFINED, ANOTHER_CONSTANT, SOME_OTHER_CONSTANT . Note that some_field may not be in each item in the list, same for some_other_field

first_packet = None
second_packet = None
third_packet = None
packets_found =  0

for packet in packets:
    val = packet.get('some_field', None)
    if (val == A_CONSTANT_I_HAVE_DEFINED) and (first_packet is not None):
        first_packet = packet
        packets_found += 1
    elif (val == ANOTHER_CONSTANT) and (second_packet is not None):
        second_packet = packet
        packets_found += 1
    elif (packet.get('some_other_field', None) == SOME_OTHER_CONSTANT) and (third_packet is not None):
        third_packet = packet
        packets_found += 1

    if packets_found == 3:
        break

I am not clear, this might help:

a = [{'a': 1}, {'a':1, 'b':1}, {'c':1}]
filtered_list = filter(lambda x: x.get('a') or x.get('b'), a)
# OP [{'a': 1}, {'a': 1, 'b': 1}]

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM