ускорить вложенный l oop и вызвать функции в python - PullRequest
0 голосов
/ 09 июля 2020

Я программирую код python, и моя проблема в том, что этот код занимает много времени, и я хочу знать, можно ли сделать его быстрее? У меня есть два списка кортежей, как показано ниже:

Similarities = [(1, 1, 1.0),(1, 2, -0.0016),(1, 3, 0.01764),(1, 4, -0.0033),(1, 5, -0.0016),...]

и

Trust = [(2, 104, 1),(5, 1509, 1),(6, 1192, 1),(7, 1510, 1),(12, 234, 1),(15, 652, 1),...]

длина Similarities = 2274064 и длина Trust = 37997, мои наборы имеют формат: (i,j,value)

Я хочу проверить кортежи, если i и j находятся в диапазоне l oop, функция возвращает их значения l oop и после проверки, существуют ли эти значения или нет, d будет вычислено. И затем количество d будет добавлено к 2D-массиву.

Теперь я хочу запустить следующий код:

totalDistance=[]
totalSim=[]
for i in range(1642):
    totalDistance.append([])
    totalSim.append([])
    for j in range(1642):
        //search in Trust list to find value of trust i and j
        tr=calcTrustDif(i,j)
        //search in Similarities list to find value of similarity i and j
        pc=calcPccDif(i,j)
        if tr and pc:
            d=math.sqrt(pow(pc,2)+pow(tr,2))
        elif tr and not(pc):
            d=tr
        elif pc and not(tr):
            d=pc
        else:
            d=3
        totalSim[i].append(1-d)
        totalDistance[i].append(d)
def calcTrustDif(i,j):
    
    tr=[t for t in Trust if t[0]== i and t[1]==j]
    if tr:
        return tr[0][2]
    else:
        pass
def calcPccDif(i,j):
    
    pc=[t for t in Similarities if t[0]== i and t[1]==j]
    if pc:
        return 1-pc[0][2]
    else:
        pass

Я оценил и обнаружил, что этот код займет 82 часа и это очень плохо ... может ли кто-нибудь помочь мне сократить время выполнения? Я думаю, что python имеет магические особенности для этой ситуации, которых я не знаю.

1 Ответ

1 голос
/ 09 июля 2020

Вам следует ознакомиться с временной сложностью и нотацией Big O .

Причина, по которой ваш код работает так медленно, заключается в том, что вы используете тройное вложенное for циклы, которые приводят к очень плохой временной сложности ~, особенно O(n*n*(allT+allP)), где n = 1642 в вашем случае.

Я бы рекомендовал попытаться придумать алгоритм, в котором вам не нужно повторять через allP и allT 1642*1642 раз. Простой выбор лучшего алгоритма может значительно улучшить время выполнения без необходимости прибегать к "Python magi c" .

Примечание: вы можете упростить другим понимание того, что вы пытаетесь добиться с помощью своего кода, если бы вы использовали более значимые имена для своих переменных. Например, значение calcPccDif(), allP, allT может быть очевидным для вас, но оно ничего не значит для других и, таким образом, затрудняет чтение вашего кода другими. (С другой стороны, totalDistance ясно и значимо.)

...