一种有效地从列表中消除特定元素的功能

时间:2019-02-01 21:10:57

标签: python python-3.x loops

我想创建一个函数(不使用库),该函数将三个整数(> 0)( a b c ),例如:

a = 6
b = 6
c = 3

并返回一个包含 c 个元素的列表(因此,在这种情况下,返回的列表应包含3个元素)取自 a 个数字的列表(因此,初始列表为[1,2,3,4,5,6])。返回列表的 c 元素必须是从 a <列表中每个 b 位置删除一个数字后设法保留在初始列表中的元素。 / strong>元素,直到len(return_list)= c

因此,对于 a = 6, b = 6和 c = 3,该函数应执行以下操作:

1) initial_list = [1,2,3,4,5,6] 
2) first_change = [2,3,4,5,6] #the number after the 6th (**b**) is 1 because after the last element you keep counting returning to the first one, so 1 is canceled
3) second_change = [2,4,5,6] #you don't start to count positions from the start but from the first number after the eliminated one, so new number after the 6th is 3 and so 3 is canceled
4) third_change = [2,4,5] #now the number of elements in the list is equal to **c**

请注意,如果在计数时最终完成列表中的元素,则继续进行计数并返回到列表的第一个元素。

我做了这个功能:

def findNumbers(a,b,c):  
count = 0
dictionary = {}
countdown = a
for x in range(1,a+1):
    dictionary[x] = True
while countdown > c:
    for key,value in dictionary.items():
        if value == True:
            count += 1
            if count == b+1:
                dictionary[key] = False
                count = 0
                countdown -= 1
return [key for key in dictionary.keys() if dictionary[key] == True]

在某些情况下它可以工作,例如上面的示例。但这并非每次都有效。 例如:

findNumbers(1000,1,5)

返回:

[209, 465, 721, 977]    #wrong result

代替:

[209, 465, 721, 849, 977] #right result

以及更大的数字,例如:

findNumbers(100000, 200000, 5)

完成它的工作要花费太多时间,我不知道问题出在我的算法效率低下还是因为代码中有些东西给Python带来了问题。我想知道一种针对这种情况的不同方法,该方法可能更有效,并且能够在每种情况下工作。谁能给我一些提示/想法? 预先感谢您的宝贵时间。如果需要更多说明和/或示例,请告诉我。

2 个答案:

答案 0 :(得分:1)

您可以跟踪这样删除的最后一个列表项的索引:

def findNumbers(a, b, c):
    l = list(range(1, a + 1))
    i = 0
    for n in range(a - c):
        i = (i + b) % (a - n)
        l.pop(i)
    return l

使findNumbers(6, 6, 3)返回:

[2, 4, 5]

findNumbers(1000, 1, 5)返回:

[209, 465, 721, 849, 977]

findNumbers(100000, 200000, 5)返回:

[10153, 38628, 65057, 66893, 89103]

答案 1 :(得分:0)

我认为我可以对该问题进行递归,所以我写了这个:

def func(a,b,c):
  d = [i+1 for i in range(a)]
  def sub(d,b,c):
    if c == 0: return d
    else:
      k = b % len(d)
      d.pop(k)
      d = d[k:] + d[:k]
      return sub(d,b,c-1)
  return sub(d,b,a-c)

因此,func(6,6,3)成功返回:[2, 4, 5],而func(1000,1,5)返回:[209, 465, 721, 849, 977],但有错误。

事实证明,对于a > 995的值,将引发以下标志:

RecursionError: maximum recursion depth exceeded while calling a Python object

没有必要尝试func(100000,200000,5)-经验教训。

我还是决定不共享代码,而是决定共享它。它可以作为递归思维的预防措施。