Home > database >  Check if value of parameter in each dict of a list is sequential
Check if value of parameter in each dict of a list is sequential

Time:10-08

I want to check if the current id equals last id 1, (this should work for any number of similar dicts added in the list)

Code

listing = [
    {
        'id': 1,
        'stuff': "othervalues"
    },
    {
        'id': 2,
        'stuff': "othervalues"
    },
    {
        'id': 3,
        'stuff': "othervalues"
    }
]

for item in listing :
    if item[-1]['id'] == item['id'] 1:
        print(True)

Output

Traceback (most recent call last):
  File "C:\Users\samuk\Desktop\Master\DV\t2\tester.py", line 10, in <module>
    if item[-1]['id'] == item['id'] 1:
KeyError: -1

Desired result

True

or, in case of fail,

False

CodePudding user response:

To check if all the ids are in a sequence we can use enumerate here.

def is_sequential(listing):
    start = listing[0]['id']
    for idx, item in enumerate(listing, start):
        if item['id'] != idx:
            return False
    return True

CodePudding user response:

You can save the last id in a variable.

id = listing[0]['id']

for item in listing[1:]:
    if id == item['id']:
        print(True)
    else:
        print(False)
    id = item['id']

CodePudding user response:

As the saying goes... "There are many ways to skin a cat". So here's another way:

listing = [
    {
        'id': 1,
        'stuff': "othervalues"
    },
    {
        'id': 2,
        'stuff': "othervalues"
    },
    {
        'id': 3,
        'stuff': "othervalues"
    }
]
for i, v in enumerate(listing[1:], 1):
    print(v['id'] - 1 == listing[i-1]['id'])

Of course, rather than just checking like this you could always sort the list!

CodePudding user response:

When you do for item in some_list, item is the actual item in that list. You can't get the previous item by item[-1].

So in your case, item is a dictionary that has the keys 'id' and 'stuff'. Obviously, no key called -1, so you get a KeyError.

You can iterate over two slices of the list after using zip() -- one that starts at the zeroth element, and one that starts on the first element. Using zip(), you can get corresponding items of these slices simultaneously. You'll have every item and its subsequent item coming out of zip().

Also, you want a result after you've checked all pairs of items, not while you're checking each pair. To do this, create a variable is_sequential with an initial value of True. If you find a single pair that doesn't work, change this to False, and break out of the loop because one pair being non-sequential makes the entire list so.

is_sequential = True
for item1, item2 in zip(listing, listing[1:]):
    if item1['id']   1 != item2['id']:
        is_sequential = False
        break

print(is_sequential)

Alternatively, you could use the any() function with the same loop and condition, and then invert the result, or use all() with the opposite condition:

# use any()
is_sequential = not any( item1['id']   1 != item2['id']
                     for item1, item2 in zip(listing, listing[1:])  
                    )

# or, use all()
is_sequential = all( item1['id']   1 == item2['id']
                     for item1, item2 in zip(listing, listing[1:])  
                    )

CodePudding user response:

You could also use sorted and range to evaluate if the identifiers are sequential:

def is_sequential(records: dict, key: str) -> bool:
    values = [value[key] for value in records]
    return sorted(values) == list(range(min(values), max(values) 1))

print(is_sequential(listing, "id"))

Note: Solution is based on approach #1 in this example and only works with integers.


However, I like Pranav Hosangadi's approach with a list comprehension better. But I would replace not any() with all() as suggested by Ch3steR in the comments:

def is_sequential(records: dict, key: str) -> bool:
    return all(l[key] 1 == r[key] for l, r in zip(records, records[1:]))

print(is_sequential(records, "id"))

Ch3steR's solution is probably the most readable code.

  • Related