Heinrich
Heinrich

Reputation: 289

Python - Enforce non-occurence of bool in list

I want to check in python 2.7 if a dictionary satisfies some restrictions I set. An satisfying example is: {1:[2], 2: [2,3], 3:False, 4: True}, however {1:[1, True]} is not ok. I want to forbid that keys map to True or False which are inside a list. Note, that I only want to detect if my restrictions are violated, I don't want to handle the case.

In the beginning I tested if a key maps to a list, and if it does I test if I have for some entry v: v == False or v == True, and if so I raise an ValueError. Then I learned that it does not work, because 1 == True is true.

Should I instead test v is False or v is True? Do you have suggestions on how to enforce the restrictions, or do you think my restrictions are bad practice?

Background: The dictionary maps state/label-tuples to successor states for an NFA, and I map to True and False to immediately accept/reject the word.

Upvotes: 0

Views: 46

Answers (2)

Lev Levitsky
Lev Levitsky

Reputation: 65831

You can use isinstance:

In [16]: isinstance(True, bool)
Out[16]: True

In [17]: isinstance(1, bool)
Out[17]: False

You can use is as well:

In [18]: any(x is True or x is False for x in [True, 2])
Out[18]: True

An example one-line function with isinstance:

In [21]: is_good = lambda d: not any(any(isinstance(x, bool) for x in l)
   ....: for l in d.values() if isinstance(l, list))

In [22]: d = {1:[2], 2: [2,3], 3:False, 4: True}

In [23]: is_good(d)
Out[23]: True

In [24]: d[1][0] = False

In [25]: is_good(d)
Out[25]: False

A more explicit version of the same function:

def is_good(d):
    for v in d.values():
        if isinstance(v, list):
            for x in v:
                if isinstance(v, bool):
                    return False
    return True

Upvotes: 1

Johan Lundberg
Johan Lundberg

Reputation: 27038

To respect duck-typing, if I did not want elements with a length to test true, I would test that, using len(), in addition to == True:

def issingle(v):
  try:
    len(v)
    return False
  except:
    return True

x=[2,3]
y=1

issingle(x) ->> False
issingle(y) ->> True

Upvotes: 0

Related Questions