Forum Archive

How to check that a key has exactly 1 value in a dictionary?

cloudytechi147

I have this python copy directory:

{128: ['S', 'S', 'O', 'F'], 512: ['S', 'F']}

I would like to be sure that each key has exactly one value 'F' and one value 'S' and return a message if it's not the case

I tried this but it didn't seem to work: it didn't print the message

for key in d:
    if not re.search(r"[F]{1}","".join(d[key])) or not re.search(r"[S].{1}","".join(d[key])):
        print(f"There is no start or end stop for the line {i}.")

Thanks in advance

ccc

I see this as two problems. (I think you are trying to solve 1.)
1. 'S' appears twice in d[128] so to make sure that does not happen, I would use a set, not a list like:
* {128: {'S', 'O', 'F'}, 512: {'S', 'F'}} # Sets guarantee that there are no duplicate values.
2. 'S' and 'F' appear in both d[128] and d[512] which you can detect with:
* set(d[128]) & set(d[512]) # --> {'F', 'S'}

https://docs.python.org/3/tutorial/datastructures.html#sets

cvp

@cloudytechi147 if I correctly understand your request (topic's title) and that you allow multiple F or S in a line:

d = {128: ['S', 'S', 'O', 'F'], 512: ['S', 'F']}
for key in d:
    if not (d[key].count('F') == 1 and d[key].count('S') == 1):
        print(f"There is no start or end stop for the line {key}.")
JonB

I feel like this might be a good case for an assert, which checks a condition and raises an exception in one statement -- assuming you want an error here, and not just a print of all problems.

for key,value in d.items():
   for s in ['S','F']:
      assert value.count(s)==1, f"Found {value.count(s)} {s} in line {key}"
ccc
for key, value in d.items():
    assert len(value) == len(set(value)), f"d[{key}] = {value} has duplicate values"

AssertionError: d[128] = ['S', 'S', 'O', 'F'] has duplicate values

cvp

@ccc yes but also True if duplicate of '0' and he asks for only S and F...