简体   繁体   中英

Select an element that satisfies a condition

I would like to select a specific element that satisfies a condition from a (very long) list. In my specific case each item in the list is a class and the condition I want is, for example, item.id == 1.

I started with

[item for item in collection if item.id == 1]

but I don't want to traverse the whole list because I am sure there is only one element that satisfied the condition.

The other option is

def check(collection):
    for item in collection:
        if item.id == 1:
            return item

Is there a more efficient way? Does Python 3 have a build in function for that? Another option could be to preprocess the list in order to obtain a dictionary, eg

{item.id : item for item in collection}

You can use a generator expression and the next() function :

item = next((item for item in collection if item.id == 1), None)

This'll find the first matching element in the collection, or return None if there is no match. It'll not iterate and evaluate any more than is strictly required to find that one element.

However, if you do need to do this a lot, creating the mapping just once then querying that each time is going to be more efficient:

mapping = {item.id: item for item in collection}
item = mapping.get(1)

as that'll limit looping to just once, then use the O(1) lookup performance. It is a memory-vs-speed trade-off.

To get the first element that satisfies a condition, use next() as outlined in the ninja's answer .

To get an element that satisfies a condition and check that it's the only one such, I use the following function:

def single(seq):
    """Checks that the sequence has a single element and returns it."""
    """Analogous to .Net LINQ's Single()"""
    if hasattr(seq,"__len__"):
        assert len(seq)==1
        return seq[0]
    else:
        i=iter(seq)
        try: value=i.next()
        except StopIteration: raise AssertionError()
        try: i.next()
        except StopIteration: return value
        else: raise AssertionError()

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