Python:根据条件划分列表的元素

Python: divide elements of a list based on a condition

我正在寻找前 20 个自然数的最小公倍数(欧拉计划问题 5)。为此,我的算法是:

  1. 列表中有数字 1 到 20
  2. 仅除列表中可被 i 整除的元素,其中 i 在范围 (2-20) 内。
  3. 无论列表中剩下什么数字,将它们相乘就是 lcm。

这是我们第一次在学校实际使用计算lcm的最朴素的算法。

现在,我不知道如何根据条件划分列表的元素。 我试过:

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
for x in a:
    if(x%2==0):
        x=x/2

这似乎不起作用。 我也试过:

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
a1=[if(x%2==0): x/2 for x in a]

上面的 if 条件后有和没有“:”。这是行不通的。我有以下问题:

一个。为什么第一个循环不能正常工作?

b。谁能告诉我该怎么做?

c。我的算法能正常工作吗?

a) 变量 x 取列表 a 的值,但没有修改,它不是列表的引用,下面的代码做你想要的:

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
for i in range(len(a)):
  if(a[i]%2==0):
    a[i]=a[i]/2

b) y C)

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

def f(x):
  if(x%2==0): 
    return x/2
  return x

a1=[f(x) for x in a]

Whatever numbers are left in the list, multiply them and that will be the lcm.

reduce(lambda x, y: x*y, a1)

a. Why isn't the first loop working correctly?

同理:

b. Can someone tell me how I can do this?

您可以执行以下任一操作:

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
for i, x in enumerate(a):
    if x%2==0:
        a[i]=x/2

或者:

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
a1=[x/2 if x%2==0 else x for x in a]

c. Will my algorithm work correctly?

我不这么认为。你最终会把每个人除以自己,结果总是 1。

但是 SO 中还有其他问题有简单的答案,例如:

find least common multiple of numbers 1-20

a) 为什么这个循环不能正常工作?

如@jose-ricardo-bustos-m 所示,x 不是引用,是数组 a 中每个元素的本地副本,并且不能修改循环。您可以改用:

a=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
for i,x in enumerate(a): #used to provide a value, and an index
    if(x%2==0):
        a[i]=x/2

b) 谁能告诉我该怎么做?

您可以尝试使用三元 if 运算符和列表理解:

a = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
b = [x/2 if x%2==0 else x  for x in a]

c) 我的算法能正常工作吗

您必须记住您已经使用过的数字,并且您可能需要多次除以同一个数字。但是如果你这样做,并继续除以相同的数字 _until 结果列表等于前一个,然后移动到下一个,你可以稍后乘以所有使用的数字,乘以列表的其余部分(但如果你去到列表中的最大数量,剩下的列表将只包含 1)。

def f(l,n): # divides items in a which are divisible by n, or leaves them
    return [x/n if x%n==0 else x  for x in l]

lcm = 1
a=[2,3,4,5,6,7]

# we go from the smallest to the largest number in your list
for i in range(2,max(a)+1):
    repeat_next_time = True
    while repeat_next_time:
        b = f(a,i)
        if a != b:
            print('Using %s as a factor' % i)
            a = b
            lcm *= i
            # print(a) # to get the status of the a list
        else:
            repeat_next_time = False
# finally, for numbers which might have not been divided yet,
# multiply the lcm by all of the remaining items
lcm *= reduce(lambda x,y: x*y, a)

即使列表中有公约数或重复数字,它也能正常工作。例如,尝试 a = [2,2,2],或 a = [2,3,6],或 a = [8,7,4,7]