Python - Hexadecimal to Decimal conversions
First -- document your code!  I read through your d_func function and here's my attempt at writing a docstring for what it does, with Python-2-compatible type hints.  Hopefully I got it right.  :)

def d_func(digit, mode):
    # type: (Union[str, int], int) -&gt; Union[int, str, None]
    """Mode 1: give the int value of the hex digit.
    Other modes: give the hex digit of the given value.
    Returns None if you give it a bad value, I guess?
    """
    if mode == 1:
        for x in range(len(d_dict.keys())):
            if digit == list(d_dict.keys())[x]:
                return x
    else:
        for y in range(len(d_dict.values())):
            if digit == list(d_dict.values())[y]:
                return list(d_dict.keys())[y]
    return None  # stumblebum


Right off the bat: this should not be one function.  (The fact that it can return either an int or a str depending on its input type is a good clue!)  You should have one function that converts value to digit and another that converts digit to value; there's no value at all to having one function that does completely different things depending on a flag you pass it.

Second: yes, this can be a lot simpler.  I think you could implement d_func as follows:

d_dict = {"0" : 0, "1" : 1, "2" : 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, "9" : 9, "A" : 10, "B" : 11, "C" : 12, "D" : 13, "E" : 14, "F": 15}
d_dict_reverse = {v: d for d, v in d_dict.iteritems()}  # this is just building a new dictionary with the keys and values swapped

def d_func(digit, mode):
    # type: (Union[str, int], int) -&gt; Union[int, str]
    if mode == 1:
        return d_dict[digit]
    else:
        return d_dict_reverse[digit]


At that point, it doesn't need to be a function at all, because you're just doing a simple dictionary lookup.  Give your dictionaries reasonable names that say what they do:

digit_to_value = {
    "0" : 0, "1" : 1, "2" : 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, 
    "8" : 8, "9" : 9, "A" : 10, "B" : 11, "C" : 12, "D" : 13, "E" : 14, "F": 15
}
value_to_digit = {v: d for d, v in digit_to_value.iteritems()}


and then instead of:

d_num = d_num + 16 ** p * d_func(h_num[digit - 1], 1)


do:

d_num = d_num + 16 ** p * digit_to_value[h_num[digit - 1]]


and instead of:

    for f in f_list[::-1]:
        h_num += d_func(f, 2)


do:

    for f in f_list[::-1]:
        h_num += value_to_digit[f]


With this approach, not only do you not have to write a function, but unlike your function the dictionary will automatically raise a KeyError if you provide the wrong kind of input, e.g. if you do value_to_digit[100] or digit_to_value[1].  Raising an error ASAP when you mess up (aka "fail fast") is good, because it makes it easier to figure out exactly where your bug is.  :)