Is this what you are after?
dd = defaultdict(None, {0: [((u'blood', u'test'), (2148, 'lab'), (1, 2), ''), ((u'crocin',), (u'47444.0', 'med'), (0,), '')],
1: [((u'back', u'pain'), (98, 'hc'), (0, 1), '')]})
for list_of_tuples in dd.values():
for tuples in list_of_tuples:
for tup in tuples:
if len(tup) == 2:
# Check if the 1st tuple element is a string
if type(tup[1]) is not str:
continue
# Check if the 0th tuple element is a number
if type(tup[0]) is int:
is_number = True
else:
try:
float(tup[0])
is_number = True
except ValueError:
is_number = False
if is_number:
print("number-string pair found:", tup)
Output:
number-string pair found: (2148, 'lab')
number-string pair found: ('47444.0', 'med')
number-string pair found: (98, 'hc')
Because some of the numbers are actually stored and strings, you've got to check if they are valid numbers with int
and float
.
Refactored to clean up the logic:
for list_of_tuples in dd.values():
for tuples in list_of_tuples:
for tup in tuples:
if len(tup) == 2 and isinstance(tup[1], str):
try:
_ = float(tup[0])
print("number-string pair found:", tup)
except ValueError:
pass
Actually, and isinstance(tup[1], str)
in the conditional statement is probably not needed.
A generator that can be iterated:
def f(d):
for list_of_tuples in dd.values():
for tuples in list_of_tuples:
for tup in tuples:
if len(tup) == 2 and isinstance(tup[1], str):
try:
_ = float(tup[0])
yield tup
except ValueError:
pass
for thing in f(dd):
print(thing)