从列表中删除元素,使用另一个列表作为索引

时间:2015-02-19 21:16:34

标签: python loops

我有一个列表primeList和另一个列表ls。 primeList是一个完整的列表,我需要删除ls中具有primeList索引的值。

例如,如果primelist = [1, 3 , 5]ls = [1, 2, 3, 4, 5, 6, 7],则应从ls中移除索引1,3和5,使ls = [1, 3, 5, 7]

目前我正在尝试使用这段代码:

primeList = list(getPrimes())
    ls = list(ls)
    for i in primeList:
        del ls[i]
    return ls

这给了我以下错误:

Traceback (most recent call last):
File "C:/Python34/My Scripts/NLP lab2/exec2.py", line 26, in <module>
otherList = delPrimes(myList)
File "C:/Python34/My Scripts/NLP lab2/exec2.py", line 18, in delPrimes
del ls[i]
IndexError: list assignment index out of range`

我相信这是因为getPrimes是一个比ls更大的列表,但是我不确定如何在Python中解决这个问题?

编辑 - 这是我目前的所有代码:

def delPrimes(*ls):

def getPrimes():
    L = []
    for x in range(2, 230):
        isPrime = True
        for y in range(2, x):
            if x % y == 0:
                isPrime = False
        if isPrime:
            L.append(x)
    return L

primeList = list(getPrimes())
ls = list(ls)
for i in primeList:
    del ls[i]
return ls

  myList = list(range(1, 51))

  print(myList)
  print("--" * 40)

  otherList = delPrimes(myList)

  print(otherList)

作为一些功课的一部分,我们需要&#34;在Python中编写一个方法来删除列表中主要索引位置的项目(直到索引位置50)。例如。它将删除索引位置2,3,5,7,...&#34;我也相信我们必须使用&#39; del&#39;删除。

EDIT2:

for i in reversed(primeList):
        if i <= len(ls):
            del ls[i]
        else:
            continue
return ls

2 个答案:

答案 0 :(得分:6)

使用列表推导来避免更改列表:

return [v for i, v in enumerate(ls) if i not in primeList]

您正在逐个删除列表前面的元素,因此其他元素每个都向上移动一个位置。在第一次删除之后,其余的索引然后是一个一个,然后是两个,等等:

>>> ls = [1, 2, 3, 4, 5, 6, 7]
>>> del ls[1]
>>> ls
[1, 3, 4, 5, 6, 7]
>>> ls[3]
5
>>> del ls[3]
>>> ls
[1, 3, 4, 6, 7]
>>> ls[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

可以改变ls,但是你需要反向处理索引,这样你才能删除那些尚未转移的索引:

for index_to_remove in reversed(primeList):
    del ls[index_to_remove]

但是因为你已经制作了一份在这里没有必要的副本。

答案 1 :(得分:0)

在我做之前,我看到Martijn给出了一个完整的答案。他的回答是正确的,所以我对他进行了投票。如果有什么不清楚的问题。对您的代码发表评论。

您的代码粘贴不当或不正确。你在函数外面有一个return语句。除此之外,我将尝试猜测你的意图是什么,因为代码是冥想。

如果您使用*,那么您正在做一些称为解包值的事情。我不认为这对你需要的东西是必要的。

>>> def test(*ls):
        print ls
>>> test("a", "b", "c")
('a', 'b', 'c')
>>> ls = [1,2,3]
>>> test(ls)
([1, 2, 3],)

>>> def test(ls):
    print ls
>>> test("a", "b", "c")

Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    test("a", "b", "c")
TypeError: test() takes exactly 1 argument (3 given)

我不太确定你真的打算这样做。

你也可以改写你的getPrimes功能,这样你就不需要花时间计算所有这些素数(授予它目前是一个很小的数字,但是因为我&#39 ;我已经给出了#34;提示&#34;为什么不给予)

def getPrimes(top):
    L = []
    for x in range(2, top+1):
        isPrime = True
        for y in range(2, x):
            if x % y == 0:
                isPrime = False
        if isPrime:
            L.append(x)
    return L

现在您可以调用该函数:

>>> getPrimes(7)
[2, 3, 5, 7]

即使您的列表并不总是相同的,这也很有用,因为您总是可以通过询问来调用该函数。

>>> getPrimes(max(ls))
[2, 3, 5, 7]

max(ls)处于显而易见的状态,并返回列表中最大的元素(您拥有的最高素数)。 之后只需遵循Martijns关于如何删除元素的说明(颠倒顺序)。

由于Python是动态类型语言,因此您不需要将函数的返回显式转换为类型。因此list在行primeList = list(getPrimes())ls = list(ls)中确实不是必需的,除非ls从一开始就不是列表。您很可能拥有该行,因为您的函数中有解包运算符*,然后返回([1, 2, 3],)这是一个类型元组(,)(&#34;一对值&#34; )以列表[1,2,3]作为第一个元素。

希望我帮助澄清一些事情。快乐的编程。