Rule based link processing Here is piece of code with few if ... else, I appreciate if anyone can clean it.

def process_link(post_script_link_list,read_str):
    links_list1 = ['Wq','Ws','Wi','Wd']
    bad_list = ['How long','how long','How much','how much']
    links_list2 = ['Qd']
    result = ''
    for item in bad_list:
        if item in read_str:
            return
    sent_split = read_str.split()
    for linking in post_script_link_list:
        sub_link = re.search('\((.*?)\)',linking).group(1)
        if sub_link in links_list1:         
            if ('Who').lower() in sent_split or 'Who' in sent_split:
                result = 'person'
                break
            elif (('Where').lower() in sent_split or 'Where' in sent_split) and 'What' not in read_str and 'what' not in read_str:
                result = 'location'
                break
            elif ('Why').lower() in sent_split or 'Why' in sent_split:
                result = 'reason'
                break
            elif ('How many').lower() in read_str or 'How many' in read_str:
                result = 'count'
                break
            elif (('When').lower() in sent_split or 'When' in sent_split) and 'What' not in read_str and 'what' not in read_str:
                result = 'time'
                break
            elif (('How').lower() in sent_split or 'How' in sent_split) and ('How long').lower() not in read_str and 'How long' not in read_str and ('How much').lower() not in read_str and 'How much' not in read_str:
                result = 'manner'
                break
        elif sub_link in links_list2:
            check_yn = verify_yesno(post_script_link_list)
            if check_yn == 1:
                result = 'Yes/No'
                break
            elif check_yn == 0:
                result = 'noresult'
                break
            break
        else:
            result = 'noresult'
    return result
For lines like

if ('Who').lower() in sent_split or 'Who' in sent_split:


you have some extra brackets and can do some manual constant folding, to get

if 'who' in sent_split or 'Who' in sent_split:


Perhaps you meant

if 'who' in read_str.lower().split():


?

Assuming so, this would simplify the main part to

if  'who' in read_str.lower().split()::
    result = 'person'
    break
elif 'where' in read_str.lower().split(): and 'what' not in read_str.lower():
    result = 'location'
    break
elif 'why' in read_str.lower().split()::
    result = 'reason'
    break
elif 'how many' in read_str.lower():
    result = 'count'
    break
elif 'when' in read_str.lower().split(): and 'what' not in read_str.lower():
    result = 'time'
    break
elif 'how' in read_str.lower().split(): and 'how long' not in read_str.lower() and 'how much' not in read_str.lower():
    result = 'manner'
    break


This can be encoded in a data structure:

# Give this a better name
def process(read):
    in_notin_result = (
        ('who',      [],       'person'),
        ('where',    ['what'], 'location'),
        ('why',      [],       'reason'),
        ('how many', [],       'count'),
        ('when',     ['what'], 'time'),
        ('how',      ['how long', 'how much'], 'manner'),
    )

    words = read.split()

    for in_sent, notin_read, result in in_notin_result:
        if in_sent in words and all(disallowed not in read for disallowed in notin_read):
            return result

    return None


This says that each if is of the form

word which must be in read.split()
some words (0, 1 or 2) which must not be in read
a result value


We put that in the data structure and loop over it:

for in_sent, notin_read, result in in_notin_result


We check the in_sent in words and that disallowed not in read for every disallowed in the words which must not be in read. If this matches, we return result, otherwise we go to the next iteration of the loop.

This can be simplified:

elif sub_link in links_list2:
    check_yn = verify_yesno(post_script_link_list)
    if check_yn == 1:
        result = 'Yes/No'
        break
    elif check_yn == 0:
        result = 'noresult'
        break
    break


to

elif sub_link in links_list2:
    check_yn = verify_yesno(post_script_link_list)
    result = 'Yes/No' if check_yn else 'noresult'
    break


Note further that 

('How long').lower() not in read_str and 'How long' not in read_str and ('How much').lower() not in read_str and 'How much' not in read_str:


will always be True because of the first filter agains bad_strings.

I would short-circuit the return instead of breaking. It seems to me that you want to return noresult on no result, but you default to ''. If you just default to 'noresult this would be easier.

for linking in post_script_link_list:
    sub_link = re.search('\((.*?)\)', linking).group(1)

    if sub_link in ['Wq','Ws','Wi','Wd']:
        process_result = process(read_str)
        if process_result is not None:
            return process_result

    elif sub_link in ['Qd']:
        return 'Yes/No' if verify_yesno(post_script_link_list) else 'noresult'

return 'noresult'


but if you do really want to distinguish these cases you'll need to use your original variant:

result = ''
for linking in post_script_link_list:
    ...

    else:
        result = 'noresult'

return result


It's not clear because I don't know what the code is meant to do.

This is what I've ended with. I don't know if it works:

# Give this a better name
def process(read):
    in_notin_result = (
        ('who',      [],       'person'),
        ('where',    ['what'], 'location'),
        ('why',      [],       'reason'),
        ('how many', [],       'count'),
        ('when',     ['what'], 'time'),
        ('how',      [],       'manner'),
    )
    words = read.split()
    for in_sent, notin_read, result in in_notin_result:
        if in_sent in words and all(disallowed not in read for disallowed in notin_read):
            return result
    return None

def process_link(post_script_link_list, read_str):
    read_str = read_str.lower()

    for item in ('how long', 'how much'):
        if item in read_str:
            return

    for linking in post_script_link_list:
        sub_link = re.search('\((.*?)\)', linking).group(1)

        if sub_link in ['Wq','Ws','Wi','Wd']:
            process_result = process(read_str)
            if process_result is not None:
                return process_result

        elif sub_link in ['Qd']:
            return 'Yes/No' if verify_yesno(post_script_link_list) else 'noresult'

    return 'noresult'