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

时间:2015-04-24 17:02:38

标签: python algorithm control-flow

我试图找到前20个自然数的最小公倍数(项目欧拉问题5)。为此,我的算法是:

  1. 列表中的数字1到20
  2. 只划分列表中可被i整除的那些元素,其中i在范围内(2-20)。
  3. 无论列表中剩下哪些数字,都要乘以它们,这将是lcm。
  4. 这是我们实际上用来首次在学校计算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条件之后。这不起作用。我有以下问题:

    一个。为什么第一个循环没有正常工作?

    湾有人能告诉我怎么做吗?

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

3 个答案:

答案 0 :(得分:1)

  

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

出于同样的原因:

here

  

湾有人能告诉我怎么做吗?

你可以这样做:

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]
  

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

我不这么认为。你最终会将每个人分开,结果总是为1。

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

Foreach in Python not working as expected

答案 1 :(得分:1)

a)为什么此循环无法正常工作?

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

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]

答案 2 :(得分:0)

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]
  

无论列表中剩下什么数字,都要乘以它们,这将是lcm。

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