Q:

Best pythonic practice to avoid repeating code?

I'm not sure if this questions has been asked - couldn't find a good practice one so far.
I have two python files with exactly same package import, and a number of different methods. A couple of variables vary only, and others are the same.
IF I need to make a change to one file, I have to go to the other one to apply the same changes which doesn't seem a robust way.
I really want to keep these files separate (in two files). I never had a good grasp of idea of class. Should I need to make a class in first file having all methods, loops, variables, and call it in the second, I can then overwrite the variables if need be? 
This is how my first file looks like, apologies I should have spent some time to make it readable, but it's just to give you an idea about the structure. This code actually plots up a number of matplotlib figures. The second file would have different input files (CSV files) which then plot up different figures.
import csv
import datetime
import pylab
import sys
import time
from inspect import getsourcefile
from os.path import abspath

import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import style
from matplotlib.backends.backend_pdf import PdfPages

def get_mul_list(*args):
    return map(list, zip(*args))

def str2float(s):
    if not s == '':
        s = (float(s))
    else:
        s = np.nan
    return s

def clean_nans(x, y, num_nan_gap=24):
    x_clean, y_clean = [], []
    cnt = 0
    for _x, _y in zip(x, y):
        if np.isnan(_y):
            cnt += 1
            if cnt == num_nan_gap:
                 # on the 5th nan, put it in the list to break line
                 x_clean.append(_x)
                 y_clean.append(_y)
            continue
        cnt = 0
        x_clean.append(_x)
        y_clean.append(_y)
    return x_clean, y_clean

def csv_store_in_dict(filepath, mode):
    csv_data = open(filepath, mode)
    data = list(csv.reader(csv_data))
    csv_imported_in_dict = dict(zip(data[0], get_mul_list(*data[1:])))
    return csv_imported_in_dict

colors_list = ['deeppink', 'aquamarine', 'yellowgreen', 'orangered', 'darkviolet',
          'darkolivegreen', 'lightskyblue', 'teal', 'seagreen', 'olivedrab', 'red', 'indigo', 'goldenrod', 'firebrick',
          'slategray', 'cornflowerblue', 'darksalmon', 'blue', 'khaki', 'wheat', 'dodgerblue', 'moccasin', 'sienna',
          'darkcyan']

current_py_filepath = abspath(getsourcefile(lambda: 0))  # python source file path for figure footnote

kkk_dict = csv_store_in_dict('CSV/qry_WatLvl_kkk_xlsTS_1c_v4.csv', 'r')  # all WL kkk data stored in a dictionary
yyyddd_dict = csv_store_in_dict('CSV/qry_WatLvl_TimeSeries2_v2.csv', 'r')  # all WL kkk data stored in a dictionary
XX_info_dict = csv_store_in_dict('CSV/XX_info.csv', 'r')  # XX_name, XX_group_name, BB_Main, CC, dddd

XX_groups_chartE = ('XXH_05',
                    'XXH_16',
                    'XXH_11',
                    'DXX_27',
                    'DXX_22',
                    'DXX_21',
                    'DXX_09',
                    'DXX_07',
                    'DXX_01',
                    'DXX_05',)

y_range = [[5,10],  # chart 1
           [7,12],  # chart 2
           [3,8],  # chart 3
           [7,12],  # chart 4
           [5,10],  # chart 5
           [20,50],  # chart 6
           [12,22],  # chart 7
           [5,25],  # chart 8
           [10,15],  # chart 9
           [22,42]]  # chart 10

# Date conversion
x_kkk_date = []
x_yyy_date = []
x_kkk = kkk_dict["DateTime"]
x_yyyddd = yyyddd_dict["DateTime"]
for i in x_kkk:
    x_kkk_date.append(datetime.datetime.strptime(i, "%d/%m/%Y %H:%M:%S"))
for i in x_yyyddd:
    x_yyy_date.append(datetime.datetime.strptime(i, "%d/%m/%Y %H:%M:%S"))

# plotting XX groups
XXs_curr_grp = []
chart_num = 1  
for XX_gr_nam in XX_groups_chartE:
    for count, elem in enumerate(XX_info_dict['XX_group_name']):
        if elem == XX_gr_nam:
            XXs_curr_grp.append(XX_info_dict['XX_name'][count]) 

    fig = plt.figure(figsize=(14, 11))  

    col_ind = 0

    for XX_v in XXs_curr_grp:  
        y_kkk = kkk_dict[XX_v] 
        y_yyyddd = yyyddd_dict[XX_v] 

        y_kkk_num = [str2float(i) for i in y_kkk] 
        y_yyyddd_num = [str2float(i) for i in y_yyyddd] 

        ind_XX = XX_info_dict["XX_name"].index(XX_v)  
        BB_Main = XX_info_dict["BB_Main"][ind_XX]  
        CC = XX_info_dict["CC"][ind_XX]  
        dddd = XX_info_dict["dddd"][ind_XX]  

        def label_pl(d_type):
            label_dis = "%s (%s, %s / %s)" % (XX_v, BB_Main, CC, d_type)
            return label_dis

        x_kkk_date_nan_cln, y_kkk_num_nan_cln = clean_nans(x_kkk_date, y_kkk_num, 200)

        plt.plot_date(x_kkk_date_nan_cln, y_kkk_num_nan_cln, '-', markeredgewidth=0,
                      label=label_pl("kkk data"), color=colors_list[col_ind])  # c = col_rand

        plt.scatter(x_yyy_date, y_yyyddd_num, label=label_pl("yyy ddds"), marker='x', linewidths=2,
                    s=50, color=colors_list[col_ind])
        col_ind += 1

    XX_grp_title = XX_gr_nam.replace("_", "-")
    plt.title("kkk Levels  \n" + XX_grp_title + " Group", fontsize=20)
    plt.ylabel('wwL (mmm)')
    plt.legend(loc=9, ncol=2, prop={'size': 8})
    plt.figtext(0.05, 0.05, current_py_filepath, horizontalalignment='left', fontsize=8)  # footnote for file path
    plt.figtext(0.95, 0.05, 'Chart E%s' % (chart_num,), horizontalalignment='right', fontsize=12)  # chart number
    plt.figtext(0.95, 0.95, datetime.date.today(), horizontalalignment='right', fontsize=8)

    # FIGURE FORMATTING
    myFmt = mdates.DateFormatter('%d/%m/%Y')
    ax = plt.gca()
    ax.xaxis.set_major_formatter(myFmt)
    plt.gcf().autofmt_xdate()
    ax.set_ylim(y_range[chart_num-1])
    plt.grid()
    fig.tight_layout() 
    plt.subplots_adjust(left=0.05, right=0.95, top=0.9, bottom=0.15)
    fig_pdf_file = "PDF/OXX_grp_page %s.pdf" % (chart_num,)
    fig.savefig(fig_pdf_file)
    XXs_curr_grp = []
    chart_num += 1  # assumed charts numbering is the same as the order of plotting
plt.show()

A:

No, you do not need to define a class. You need to remove the shared functions from one file, and have it import the other. An import statement can import installed python packages, but also python files. Use it like this:
# myfile.py

def f(x):
    return x * 2

# main.py

import myfile

myfile.f(2)

Note that for this example, both files must be in the same directory.
However, if you would like to store myfile.py in a different directory, i.e. in this hierarchy:
my_project
----main.py
----my_modules
        ----myfile.py
        ----__init__.py

Simply create an empty __init__.py file in the 'my_modules' directory, and change your import statement to reflect import my_modules.myfile.

