Zeckendorf Representation of positive integer Zeckendorf's theorem states that all positive integers crepresented uniquely as the sum of one or more distinct Fibonacci numbers in such a way that the sum does not include any two consecutive Fibonacci numbers. 

So like given the input 10, the outcome would be [8,2].

This is my working code that was for Reddit's dailyprogrammer challenge: 

def fib_list(max_num):
    x=3     #starting at 3 because we have [1,1] in list already.
    list_of_fib = [1,1]
    while x &lt; max_num:
        x = list_of_fib[-1] + list_of_fib[-2]
        list_of_fib.append(x)
    return list_of_fib

def find_num_smaller(num, my_list):
    for value in reversed(my_list):
        if value &lt;= num:
            return value 

def solve(num):
    combo_list = []
    list_to_pick_from = fib_list(num)
    while num &gt; 0:
        temp_value = find_num_smaller(num,list_to_pick_from)
        num -= temp_value
        combo_list.append(temp_value)
    print(combo_list)


solve(10)


Running it through timeit.timeit I get about 0.06917929102201015 seconds with the input of 1234. Medium size input of 123456789 yields about 0.22879931901115924 seconds and a large size input of 123456789123456789123456789 yields 1.3149479770218022 seconds. Is there anyway to speed it up? Or make it more acceptable at a "higher standard"  (whatever this means, I guess some would call it 'Pythonic' but I'm not sure the correct term)? Maybe is there some better practice I can employ here. 

I have thought of turning Solve() into a generator and just get all the combo values out, but I'm not sure if that's faster. 

I know that if I were to run it multiple times, I would check if the input is within the already generated fib_list, and if it isn't I would generate a new one. But that's another question, I just want to see one input.
First some general review:


You should use a if __name__ == "__main__": guard around the test run to allow importing of your code from another module.
You should add docstrings to your functions to explain what they do. Docstrings are of the format:




def f(x, y):
    """Returns the sum of `x` and `y`"""
    return x + y




As you already mentioned, here is a way to use generators. This has two draw-backs compared to your code:


In find_num_smaller we have to iterate forwards (you cannot iterate backwards through an iterator, at least not without converting it to a list first).
We need to re-generate the generator every loop, because it will be partially exhausted




def fib(max_num):
    """
    Yields the fibonacci sequence until the last element smaller than `max_num`
    """
    n_1, n = 0, 1
    while n &lt; max_num:
        yield n
        n_1, n = n, n + n_1


def find_num_smaller(num, my_list):
    """
    Iterates through an iterator until the value in the iterator is larger than `num`. 
    Returns the value before that.
    """
    last_value = next(my_list)
    for value in my_list:
        if value &gt; num:
            return last_value
        last_value = value
    return last_value


def solve(num):
    """
    Description here
    """
    x = num
    while x &gt; 0:
        temp_value = find_num_smaller(x, fib(num))
        x -= temp_value
        yield temp_value

if __name__ == "__main__":
    print list(solve(10))


Note that your fund_num_smaller will return None if all values in my_list are smaller than num. Here I added returning the last element in that case.

However, this actually performs worse than your code (mostly because iterating reversed saves a lot of time and re-doing the fibonacci sequence wastes a lot of cycles).

As an alternative consider this code:

def find_num_smaller(num, my_list):
    for value in reversed(my_list):
        if value &lt;= num:
            return value


def solve(num):
    l = list(fib(num))
    while num &gt; 0:
        temp_value = find_num_smaller(num, l)
        num -= temp_value
        yield temp_value


Where I used your find_num_smaller and put the fibonacci into a list.

Here is acomparison between the three approaches for the input 123456789123456789123456789123456789123456789123456789 on my machine:

no generator     406 function calls in 0.000 seconds
only generators  10111 function calls in 0.003 seconds
mixed            407 function calls in 0.000 seconds


So using generators here will not give you a speed improvement for most inputs. For the fibonacci numbers it will, however, give you a memory improvement (which will take quite some time to matter).

For really large inputs (like 123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789) there is no improvement visible:

no generator  2947 function calls in 0.017 seconds
mixed         2948 function calls in 0.017 seconds


And for the input 123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789:

no generator  5886 function calls in 0.063 seconds
mixed         5887 function calls in 0.064 seconds


So both approaches seem to scale with the number of digits of the input.