если __ и __ в ___ тогда - PullRequest
       16

если __ и __ в ___ тогда

1 голос
/ 11 апреля 2011

Я пытаюсь создать скрипт, который проходит по списку.

Мне нужно просмотреть конечный список (400) идентификаторов компетенций (например, 124, 129 и т. Д. - обычные целые числа)

Затем у меня есть словарь, в котором записано, какие компетенции есть у каждого пользователя. Ключ - это имя пользователя, а значение для каждого ключа - это список целых чисел (то есть, какие компетенции есть у пользователей)

Например

User x - [124, 198, 2244 ...]
User Y - [129, 254, 198, 2244 ...]

Я собираюсь составить матрицу, подчеркивающую, как часто каждая компетенция встречается с любой другой компетенцией - матрица смежности.

Например, в приведенных выше примерах компетенция 198 встречалась с компетенцией 2244 в двух случаях. В то время как компетенции 254 и 124 никогда не возникали вместе.

Я сейчас использую этот код:

fe = []    
count = 0
competency_matches = 0
for comp in competencies_list:
    common_competencies = str("")
for comp2 in competencies_list:
    matches = int(0)
    for person in listx:
        if comp and comp2 in d1[person]:
            matches = matches + 1
        else:
            matches = matches
    common_competencies = str(common_competencies) + str(matches) + ","
fe.append(common_competencies)
print fe
print count
count = count + 1

Это не работает и просто возвращает количество повторений каждой компетенции в целом. Я думаю, что проблема заключается в строке «if comp и comp2 в d1 [person]:».

Проблема будет, например, если у человека были следующие компетенции [123, 1299, 1236], и я искал компетенцию 123, это будет возвращено дважды, так как это появляется в записях 123 и 1236. Существует ли способ принудительно установить совпадение EXACT при использовании операций if __ и __ then.

Или у кого-нибудь есть предложения по улучшению, как этого добиться ...

Заранее спасибо за любые указатели. Приветствия

Ответы [ 3 ]

8 голосов
/ 11 апреля 2011

Вы неправильно понимаете, как работает and.Чтобы проверить, есть ли два значения в списке, используйте:

if comp1 in d1[person] and comp2 in d1[person]:
  ...

Ваша версия делает что-то еще.Это связывает как это: if (comp1) and (comp2 in d1[person]).Другими словами, он интерпретирует comp1 как значение истины, а затем выполняет логическое and с проверкой включения в список.Это действительный код, но он не делает то, что вы хотите.

3 голосов
/ 11 апреля 2011

Это должно работать немного быстрее, потому что удаляет дополнительный слой итерации. Надеюсь, это поможет.

from collections import defaultdict
from itertools import combinations

def get_competencies():
    return {
        "User X": [124, 198, 2244],
        "User Y": [129, 254, 198, 2244]
    }

def get_adjacency_pairs(c):
    pairs = defaultdict(lambda: defaultdict(int))
    for items in c.itervalues():
        items = set(items)  # remove duplicates
        for a,b in combinations(items, 2):
            pairs[a][b] += 1
            pairs[b][a] += 1
    return pairs

def make_row(lst, fmt):
    return ''.join(fmt(i) for i in lst)

def make_table(p, fmt="{0:>8}".format, nothing=''):
    labels = list(p.iterkeys())
    labels.sort()

    return [
        make_row([""] + labels, fmt)
    ] + [
        make_row([a] + [p[a][b] if b in p[a] else nothing for b in labels], fmt)
        for a in labels
    ]

def main():
    c = get_competencies()
    p = get_adjacency_pairs(c)
    print('\n'.join(make_table(p)))

if __name__=="__main__":
    main()

результаты в

             124     129     198     254    2244
     124                       1               1
     129                       1       1       1
     198       1       1               1       2
     254               1       1               1
    2244       1       1       2       1        

... очевидно, таблица из 400 столбцов - это слишком много для вывода на экран; Я предлагаю использовать csv.writer (), чтобы сохранить его в файл, с которым вы можете работать в Excel или OpenOffice.

0 голосов
/ 11 апреля 2011

Ваш отступ здесь означает, что ваши два цикла не являются вложенными. Сначала вы перебираете competencies_list и устанавливаете common_competencies на пустую строку 400 раз, затем снова перебираете competencies_list и делаете то, что объяснил phooji. Я уверен, что это не то, что вы хотите сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...