Есть ли способ еще больше сократить цикл for в этом коде Python? - PullRequest
1 голос
/ 10 июня 2019

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

Например, [2,4,5] -> [20,10,8]

Я нашел решение, в котором один цикл for, j, пересекает правую сторону i-го(текущий) элемент, в то время как в другом для цикла, k покрывает левую сторону элементов - Умножает и дает результат.

def mulList():
    oldList = [2,4,5]
    newList = []
    for i in range(len(oldList)):
        a = 1
        for j in range(i+1,len(oldList)):
            a *= oldList[j] 
        for j in range(i-1,-1,-1):
            a *= oldList[j] 
        newList.append(a)
    print(newList)
mulList()

Позже я узнал, что мы можем решить это с помощью двух циклов for, таких как эта, где я ничего не делаю, если я равен j

def mulList():
    oldList = [2,4,5]
    newList = []
    for i in range(len(oldList)):
        a = 1
        for j in range(len(oldList)):
            if j == i:
                a += 0
            else:
                a *= oldList[j] 
        newList.append(a)
    print(newList)
mulList()

Мне было интересно, есть лиЛюбой лучший способ решить это только с одним для цикла.

Ответы [ 4 ]

4 голосов
/ 10 июня 2019

Вы можете просто умножить все вместе один раз, а затем снова пройтись по элементам и разделить общий продукт на текущий элемент:

def mulList():
    oldList = [2,4,5]
    newList = []
    total = 1
    for x in oldList:
        total *= x  # total = total * x
    for x in oldList:
        # Use // to get int (4) instead of float (4.0)
        newList.append(total // x)
    print(newList)
2 голосов
/ 10 июня 2019

Вы можете взять произведение всех элементов в списке через functools.reduce , а затем разделить каждый элемент в списке на произведение с помощью целочисленного деления //

from functools import reduce
from operator import mul

li = [2,4,5]
#Take product of all elements via reduce operation on the list 
mult = reduce(mul, li)
#40

#Divide the product found in the step above by each item via integer division
res = [mult//item for item in li]

print(res)

Вы также можете умножить элементы в цикле for, если не хотите использовать functools.reduce

#Or loop over the element to multiply
mult = 1
for item in li:
    mult *= item

Вывод будет

[20, 10, 8]
1 голос
/ 10 июня 2019

Я видел этот вопрос в leetcode, я думаю, и было ограничение, чтобы не использовать деление и все еще делать этот алгоритм в O(n).По сути, я пересекаю массив два раза, один раз в прямом направлении и один раз в обратном, и умножаю соответствующие элементы на третьей итерации, чтобы получить вывод, который вы видите.

oldlist = [2,4,5]
forwardlist=[1]*len(oldlist)
backwardlist=[1]*len(oldlist)
mul = oldlist[0]
for i in range(1,len(oldlist)):
    forwardlist[i] = mul
    mul*= oldlist[i]
mul = oldlist[len(oldlist) - 1]
for i in range(len(oldlist) - 2, -1, -1):
    backwardlist[i] = mul
    mul*= oldlist[i]
newlist = []
for i in range(len(oldlist)):
    newlist.append(forwardlist[i]*backwardlist[i])
print(newlist)

OUTPUT

[20, 10, 8]

Надеюсь, это было полезно.:)

0 голосов
/ 10 июня 2019

Как насчет этого

c = 1
for i in oldList:
    c *= i
newList = [c//e for e in oldList]

Теперь ваша функция будет

def mulList():
    oldList = [2,4,5]
    c = 1
    for i in oldList:
        c *= i
    newList = [c//e for e in oldList]
    print(newList)
...