Параметр по умолчанию в функции Python не всегда работает

Я читаю Программу коллективного разума и пишу часть кода более питоническим способом, чем это написано в книге, просто ради обучения.

Первая глава посвящена системам рекомендаций. На основе следующего словаря предлагаются некоторые меры сходства.

critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane':
3.5,
        'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5,
        'The Night Listener': 3.0},
    'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5,
        'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0,
        'You, Me and Dupree': 3.5},
    'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
        'Superman Returns': 3.5, 'The Night Listener': 4.0},
    'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
        'The Night Listener': 4.5, 'Superman Returns': 4.0,
        'You, Me and Dupree': 2.5},
    'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
        'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
        'You, Me and Dupree': 2.0},
    'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
        'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
    'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}

Учитывая, что unique_pairs - это список кортежей, содержащих различные возможные пары людей,

unique_pairs = list(itertools.combinations(people, 2))

unique_pairs
[('Michael Phillips', 'Mick LaSalle'),
 ('Michael Phillips', 'Lisa Rose'),
 ('Michael Phillips', 'Toby'),
 ('Michael Phillips', 'Jack Matthews'),
 ('Michael Phillips', 'Gene Seymour'),
 ('Michael Phillips', 'Claudia Puig'),
 ('Mick LaSalle', 'Lisa Rose'),
 ('Mick LaSalle', 'Toby'),
 ('Mick LaSalle', 'Jack Matthews'),
 ('Mick LaSalle', 'Gene Seymour'),
 ('Mick LaSalle', 'Claudia Puig'),
 ('Lisa Rose', 'Toby'),
 ('Lisa Rose', 'Jack Matthews'),
 ('Lisa Rose', 'Gene Seymour'),
 ('Lisa Rose', 'Claudia Puig'),
 ('Toby', 'Jack Matthews'),
 ('Toby', 'Gene Seymour'),
 ('Toby', 'Claudia Puig'),
 ('Jack Matthews', 'Gene Seymour'),
 ('Jack Matthews', 'Claudia Puig'),
 ('Gene Seymour', 'Claudia Puig')]

Я попытался улучшить функцию подобия корреляции Пирсона, предложенную в книге, добавив p-значение к результату функции, которое выводится только в том случае, если параметр p_value функции истинен. Функция определяется так:

def sim_pearson(prefs, p1, p2, p_value=False):
    """Returns the pearson correlation coefficient and the p-value (optional)
    of the ratings of the movies that both p1 and p2 have rated"""

    # Creates a list with the movies that both p1 and p2 have rated
    movies = [movie for movie in prefs[p1] if movie in prefs[p2]]

    # List of the scores that both p1 and p2 have given to the movies in common
    scores_p1 = [prefs[p1][movie] for movie in movies]
    scores_p2 = [prefs[p2][movie] for movie in movies]

    corr, p_value = scipy.stats.pearsonr(scores_p1, scores_p2)

    if p_value:
        return (corr, p_value)
    else:
        return corr

Моя проблема в том, что функция работает не так, как ожидалось, поскольку она не возвращает кортеж (коэффициент корреляции, p-значение) все время, когда p-значение равно True, и дает те же результаты, когда p_value имеет значение True. как будто это ложь. Почему это происходит и как это исправить?

Вот список, содержащий результат применения функции к каждой из возможных пар людей, чтобы увидеть, что я сказал. Результат такой же с p_value = True, что и с p_value = False, я просто вставлю первый случай.

pearson_results = [(pair[0][:5], 
                    pair[1][:5], 
                    sim_pearson(critics, pair[0], pair[1], p_value=True)) 
                    for pair in unique_pairs]

pearson_results
[('Micha', 'Mick ', (-0.2581988897471611, 0.74180111025283857)),
 ('Micha', 'Lisa ', (0.40451991747794525, 0.59548008252205464)),
 ('Micha', 'Toby', -1.0),
 ('Micha', 'Jack ', (0.13483997249264842, 0.8651600275073511)),
 ('Micha', 'Gene ', (0.20459830184114206, 0.79540169815885797)),
 ('Micha', 'Claud', 1.0),
 ('Mick ', 'Lisa ', (0.59408852578600457, 0.21370636293028805)),
 ('Mick ', 'Toby', (0.92447345164190498, 0.24901011701138964)),
 ('Mick ', 'Jack ', (0.21128856368212914, 0.73299431171284912)),
 ('Mick ', 'Gene ', (0.41176470588235292, 0.41726032973743138)),
 ('Mick ', 'Claud', (0.56694670951384085, 0.3189317919127756)),
 ('Lisa ', 'Toby', (0.99124070716193036, 0.084323216321943714)),
 ('Lisa ', 'Jack ', (0.74701788083399601, 0.14681146067336839)),
 ('Lisa ', 'Gene ', (0.39605901719066977, 0.43697492654267506)),
 ('Lisa ', 'Claud', (0.56694670951384085, 0.3189317919127756)),
 ('Toby', 'Jack ', (0.66284898035987017, 0.53869426797895403)),
 ('Toby', 'Gene ', (0.38124642583151169, 0.75098988298861025)),
 ('Toby', 'Claud', (0.89340514744156441, 0.29661883133160016)),
 ('Jack ', 'Gene ', (0.96379568187563314, 0.0082243534847899202)),
 ('Jack ', 'Claud', (0.028571428571428571, 0.9714285714285712)),
 ('Gene ', 'Claud', (0.31497039417435602, 0.60570041941160946))]

person Xoel    schedule 12.08.2017    source источник
comment
вы переопределяете p_value с помощью строки corr, p_value = scipy.stats.pearsonr(scores_p1, scores_p2), поэтому параметр, заданный функции, здесь не имеет значения   -  person PRMoureu    schedule 12.08.2017
comment
Ааа, так очевидно. Спасибо @PRMoureu!   -  person Xoel    schedule 13.08.2017


Ответы (1)


Измените нижнюю часть вашей функции на:

corr, p_value2 = scipy.stats.pearsonr(scores_p1, scores_p2)

if p_value:
    return (corr, p_value2)
else:
    return corr
person Peter Majko    schedule 12.08.2017