Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python—如果在列表中出现两次,则在两个值的索引之间删除_Python_Indexing - Fatal编程技术网

Python—如果在列表中出现两次,则在两个值的索引之间删除

Python—如果在列表中出现两次,则在两个值的索引之间删除,python,indexing,Python,Indexing,标题确实令人困惑,所以这里有一个例子:假设我有一个值列表[1,2,3,2,1,4,5,6,7,8]。我想删除列表中两个1之间的值,通过python方法,它也会删除第一个1并输出[1,4,5,6,7,8]。不幸的是,由于我缺乏pythonic能力,我只能制作一些删除第一组的东西: a = [1,2,3,2,1,4,5,6,7] uniques = [] junks = [] for value in a: junks.append(value) if value not in un

标题确实令人困惑,所以这里有一个例子:假设我有一个值列表[1,2,3,2,1,4,5,6,7,8]。我想删除列表中两个1之间的值,通过python方法,它也会删除第一个1并输出[1,4,5,6,7,8]。不幸的是,由于我缺乏pythonic能力,我只能制作一些删除第一组的东西:

a = [1,2,3,2,1,4,5,6,7]
uniques = []
junks = []
for value in a:
    junks.append(value)
    if value not in uniques:
        uniques.append(value)
for value in uniques:
    junks.remove(value)
for value in junks:
    a.remove(value)
    a.remove(value)
a[0] = 1
print(a)
[1,4,5,6,7]

适用于第一个双匹配项,而不适用于较大列表中的下一个匹配项。我有一个想法,就是在第一次出现的索引和第二次出现的索引之间删除,这将保留第二次出现的索引,而不是让我做一些愚蠢的事情,比如[0]=1,但我真的不知道如何实现它。

如果要查找唯一的元素,可以使用set和list

mylist = list(set(mylist))

如果要查找唯一的元素,可以使用set和list

mylist = list(set(mylist))

这是否符合您的要求:

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

def f(l):
    x = l.copy()
    for i in l:
        if x.count(i) > 1:
            first_index = x.index(i)
            second_index = x.index(i, first_index + 1)
            x = x[:first_index] + x[second_index:]
    return x

所以fa的输出是[1,4,5,6,7,8],f[1,2,3,2,1,4,5,6,7,8,7,6,5,15,16]的输出是[1,4,5,15,16]。

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

def f(l):
    x = l.copy()
    for i in l:
        if x.count(i) > 1:
            first_index = x.index(i)
            second_index = x.index(i, first_index + 1)
            x = x[:first_index] + x[second_index:]
    return x
所以fa的输出是[1,4,5,6,7,8],而f[1,2,3,2,1,4,5,6,7,8,7,6,5,15,16]的输出是[1,4,5,15,16]

一个更有效的解决办法是

a = [1, 2, 3, 2, 1, 4, 5, 6, 7, 8, 7, 6, 5, 15, 16]
pos1 = 0
while pos1 < len(a):
    if a[pos1] in a[pos1+1:]:
        pos2 = a.index(a[pos1], pos1+1)
        a = a[:pos1]+a[pos2:]
    pos1 += 1
print a #[1, 4, 5, 15, 16]
一个更有效的解决办法是

a = [1, 2, 3, 2, 1, 4, 5, 6, 7, 8, 7, 6, 5, 15, 16]
pos1 = 0
while pos1 < len(a):
    if a[pos1] in a[pos1+1:]:
        pos2 = a.index(a[pos1], pos1+1)
        a = a[:pos1]+a[pos2:]
    pos1 += 1
print a #[1, 4, 5, 15, 16]
这可能不是最有效的方法,但希望能有所帮助

你不能检查一下某个东西是否出现了两次吗?如果出现了,你有firstIndex,secondIndex,然后:

a=[1,2,3,4,5,1,7,8,9] b=[] 然后用一种方法得到重复数的第一个和第二个索引 对于范围为0的索引,lena: 打印索引 如果index>firstIndex和index这可能不是最有效的方法,但希望能有所帮助

你不能检查一下某个东西是否出现了两次吗?如果出现了,你有firstIndex,secondIndex,然后:

a=[1,2,3,4,5,1,7,8,9] b=[] 然后用一种方法得到重复数的第一个和第二个索引 对于范围为0的索引,lena: 打印索引
如果index>firstIndex和index完成您需要的工作:

重复值的第一个和最后一个位置 之间的所有索引,以删除它们 有趣的是,您可以简单地告诉python这样做:

# we can use a 'smart' dictionary, that can construct default value:
from collections import defaultdict

# and 'chain' to flatten lists (ranges)
from itertools import chain

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

# build dictionary where each number is key, and value is list of positions:
index = defaultdict(list)
for i, item in enumerate(a):
    index[item].append(i)

# let's take first only and last index for non-single values
edges = ((pos[0], pos[-1]) for pos in index.values() if len(pos) > 1)

# we can use range() to get us all index positions in-between
# ...use chain.from_iterable to flatten our list
# ...and make set of it for faster lookup:
to_remove = set(chain.from_iterable(range(start, end) 
                for start, end in edges))
result = [item for i, item in enumerate(a) if i not in to_remove]
# expected: [1, 4, 5, 6, 7]
print result
当然,您可以将其缩短:

index = defaultdict(list)
for i, item in enumerate([1, 2, 3, 2, 1, 4, 5, 6, 7]):
    index[item].append(i)
to_remove = set(chain.from_iterable(range(pos[0], pos[-1]) 
                    for pos in index.values() if len(pos) > 1))
print [item for i, item in enumerate(a) if i not in to_remove]
此解决方案具有线性复杂性,应该非常快。代价是
字典和集合的额外内存,所以您应该小心巨大的数据集。但是,如果您有大量数据,使用lst.index的其他解决方案无论如何都会阻塞,因为它们在^2上,有大量的解引用和函数调用。

要完成您需要的工作:

重复值的第一个和最后一个位置 之间的所有索引,以删除它们 有趣的是,您可以简单地告诉python这样做:

# we can use a 'smart' dictionary, that can construct default value:
from collections import defaultdict

# and 'chain' to flatten lists (ranges)
from itertools import chain

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

# build dictionary where each number is key, and value is list of positions:
index = defaultdict(list)
for i, item in enumerate(a):
    index[item].append(i)

# let's take first only and last index for non-single values
edges = ((pos[0], pos[-1]) for pos in index.values() if len(pos) > 1)

# we can use range() to get us all index positions in-between
# ...use chain.from_iterable to flatten our list
# ...and make set of it for faster lookup:
to_remove = set(chain.from_iterable(range(start, end) 
                for start, end in edges))
result = [item for i, item in enumerate(a) if i not in to_remove]
# expected: [1, 4, 5, 6, 7]
print result
当然,您可以将其缩短:

index = defaultdict(list)
for i, item in enumerate([1, 2, 3, 2, 1, 4, 5, 6, 7]):
    index[item].append(i)
to_remove = set(chain.from_iterable(range(pos[0], pos[-1]) 
                    for pos in index.values() if len(pos) > 1))
print [item for i, item in enumerate(a) if i not in to_remove]
此解决方案具有线性复杂性,应该非常快。代价是

字典和集合的额外内存,所以您应该小心巨大的数据集。但是如果您有大量数据,使用lst.index的其他解决方案无论如何都会阻塞,因为它们在^2上,有大量的解引用和函数调用。

这样做不会保留任何边值,因此对于[1,2,3,2,1,4,5,6,7],它将返回[4,5,6,7],而不是[1,4,5,6,7],这样做不会保留任何边值,对于[1,2,3,1,1,4,5,6,7]它将返回[4,5,6,7]而不是[1,4,5,6,7]Nah,在这种情况下,所需的输出是[1,4,5,6,7,8]。如果我们有一个更大的列表,比如a=[1,2,3,2,1,4,5,6,7,8,7,6,5,15,16],那么它也不起作用。在这种情况下,我也希望在5之间删除。@Sundrah那么你想在所有重复值之间删除吗?你不想同时保留两个1,只保留第一个,对吗?[1,2,3,1,2,3]的期望输出是什么?@Markus Meskanen是的,就是这样。@Julien Spronck这种列表在我做的算法中永远不会出现。不,在这种情况下,期望输出是[1,4,5,6,7,8]。如果我们有一个更大的列表,比如a=[1,2,3,2,1,4,5,6,7,8,7,6,5,15,16],那么它也不起作用。在这种情况下,我也希望在5之间删除。@Sundrah那么你想在所有重复值之间删除吗?你不想同时保留两个1,只保留第一个,对吗?[1,2,3,1,2,3]的期望输出是什么?@Markus Meskanen是的,就是这样。@Julien Spronck这种列表在我做的算法中永远不会出现。@Sundah这就是你想要的吗?是的,是的。他们真的需要做一件事,你可以标记一个以上的答案正确。非常感谢您的时间。您真的应该在这里使用for循环:对于lena中的pos1:因为您只是在while循环中调用pos1+=1。我不使用for循环的原因是因为我想在不创建副本的情况下更改ait@Sundrah这就是你想要的吗?是的。他们真的需要做一件事,你可以标记一个以上的答案正确。非常感谢你的时间。你应该
我在这里使用for循环:对于lena中的pos1:sinc eyou反正只是在while循环中调用pos1+=1。我不使用for循环的原因是我想更改a而不创建它的副本