0

I want to check if a list contains only a specific element (in my case its None)

I believe there is a pythonic way of doing it, I tried: if mydict[direction] == None for direction in DIRECTIONS: ...

but this obviously doesn't work

In other words I need a PYTHONIC way that allows me to shorten the next code:

def ispure(element)
    for direction in DIRECTIONS:
        if mydict[direction] != element
            return False
        else:
            pass
    return True

Hopefully I am being clear and thanks in advance.

4
  • your question is not clear, can you explain with some examples ? Commented Dec 26, 2018 at 7:40
  • I think you can try filter Commented Dec 26, 2018 at 7:40
  • If you are testing for None only, how about just if None in mydict: ...? Commented Dec 26, 2018 at 7:40
  • Something like all(i is None for i in your_list)? Commented Dec 26, 2018 at 7:45

2 Answers 2

1

The easiest (and not as efficient) way is: len(list(filter(lambda direction: mydict[direction] is not None, DIRECTIONS))) == 0

If you want to be more efficient and not go through all the elements in case the condition was false somewhere in the middle of the list, you can use takewhile:

from itertools import takewhile len(list(takewhile(lambda direction: mydict[direction] is not None, DIRECTIONS))) == len(DIRECTIONS)

Sign up to request clarification or add additional context in comments.

1 Comment

Whoa!! complex solution, you must be smart :)
0

There are multiple solutions, so you can pick your poison. Assuming a is a list of 100 Nones, here are some that I could think of (sorted by performance on my machine):


Using set:

def only_element(element, ls):
    return set(ls) == set([element])

Timing:

$ python -m timeit 'set(a) == set([None])'
100000 loops, best of 5: 3.06 µs per loop

Using all:

def only_element(element, ls):
    return all([item == element for item in ls])

Timing:

$ python -m timeit 'all([item == None for item in a])'
50000 loops, best of 5: 8.81 usec per loop

Using a for loop:

def only_element(element, ls):
    for item in ls:
        if item != element:
            return False
    return True

Timing:

$ python -m timeit 'for item in a:\n    if item != None:\n        break'
100000 loops, best of 5: 9.16 µs per loop 

Using filter:

def only_element(element, ls):
    return len(list(filter(lambda x: x != element, ls))) == 0

Timing:

$ python -m timeit 'len(list(filter(lambda x: x != None, a))) == 0'
10000 loops, best of 5: 20.8 usec per loop

What's the takeaway?

Usually, there's a built-in function that suits your needs better and runs faster (and with less code) than if you were to use a for loop.

2 Comments

The first solution is very smart, simple and intuitive I will stick to that, but can you explain the all() function I looked at the documentation but I don't quite get it.
Sure! The all function takes in a list of elements and returns if all of them are truthy. Things that are falsy (the opposite) include 0, [] (the empty list), and of course False. If any of those are in the list that is the input to all, the return value would be False. In this example, the list is converted to a list of booleans, each representing whether that item was the desired element. The all call will check if there are any Falses (meaning, if there were any elements that weren't desired) and will return False if so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.