如何修改(不删除!)Python列表中的重复元素,同时保留它们的顺序?

时间:2016-02-09 09:15:49

标签: python list duplicates

我有一个清单:

L = [0.8963, 0.8963, 0.1234, 0.3456, 0.3456, 0.3456, 0.6789]

并且只想修改重复的值,保留第一个值,并且每次都将浮点数(例如,0.0001)添加到剩余的重复值中。

我试过这段代码:

def modify_duplicates_ordered(L):
    L_mod = []
    dupl = set([x for x in L if L.count(x) > 1])
    print 'dupl', dupl
    for j in L:
        if j in list(dupl) and not L_mod:
            L_mod.append(j)
        elif j in list(dupl) and L_mod:
            j += float(0.0001)
            L_mod.append(j)
        else:
            L_mod.append(j)
    return L_mod



L_mod = modify_duplicates_ordered(L)  
print 'L_mod', L_mod

,输出为:

dupl set([0.8963, 0.3456])  
L_mod [0.8963, 0.8964, 0.1234, 0.3457, 0.3457, 0.3457, 0.6789]

'理想'输出应该是:

L_mod [0.8963, 0.8964, 0.1234, 0.3457, 0.3458, 0.3459, 0.6789]

我无法弄清楚如何修改其他重复值(此处为0.3457):我发现了大量代码来删除Python列表中的重复值(也使用enumerate()函数),但没有成功。

5 个答案:

答案 0 :(得分:1)

其中一种方式:

items = forms.IntegerField(min_value=1)

答案 1 :(得分:1)

这里有两个问题 您的列表有多大,您为此任务分配的时间是多少? 和精度问题

  1. 你想要一个O(n ^ 3),O(n ^ 2),O(n log n),O(n)解?
  2. 你的列表包含浮点数,它们如何确定两个数字是否实际上相等(例如,如果一个元素是0.9 - 0.8的输出,另一个元素是0.1逻辑/数学上它们是相等但实际上是0.9 - 0.8 = 0.09999999999999998(python 2.7,64位) - 通常要比较两个浮点数x和y,如果abs(x - y)
  3. 其他已发布的解决方案无法解决同一元素有多个重复项的情况,例如,如果有100个重复的x,那么您希望第1000次出现应该将0.1添加到其中..但是其他已发布的解决方案如此远将增加0.10000000000000184(在64位平台上)
  4. 这是我的O(n) - 数值稳定 - 解决方案,假设两个数字相等,当且仅当它们具有相同的表示时

    def modify_duplicates_ordered(original):
        D = {}
        result = [];
        for value in original: D[value] = 0;
        for value in original: 
            result.append(value + D[value] * 0.0001);
            D[value] += 1;
        return result;
    

答案 2 :(得分:0)

def modify_duplicates_ordered(L):
    if len(L) == 1:
        return L
    for ind in range(0,len(L[1:])):
        while L[ind] in L[:ind]:
            L[ind] += 0.0001
    return L

这会修改原始列表,如果您不想这样,您可以在开头复制L并改为复制

答案 3 :(得分:0)

这是一种方式:

>>> L = [0.8963, 0.8963, 0.1234, 0.3456, 0.3456, 0.3456, 0.6789]
>>> for i in range(len(L)):
...     current = L.pop(i)
...     while True:
...         try: dup_idx = L.index(current)
...         except ValueError: break
...         L[dup_idx] += .0001
...     L.insert(i, current)
...     
>>> 
>>> L
[0.8963, 0.8964, 0.1234, 0.3456, 0.3457, 0.3458, 0.6789]

我通过列表,弹出当前值,搜索重复并递增它们,将当前值放回数组中,然后转到下一个元素。

答案 4 :(得分:0)

0.0001添加到副本中时,您必须关注此情况,并在列表中提供值。

你可以这样做:

def modify_duplicates_ordered(L):
    delta = float(0.0001) # why not simply 0.0001 ?
    L_mod = []
    unique_vals = set()
    for j in L:
        while j in unique_vals:
            j += delta
        unique_vals.add(j)
        L_mod.append(j)
    return L_mod

或者,如果您希望修改列表(此版本返回None):

def modify_duplicates_ordered_inplace(L):
    delta = float(0.0001) # why not simply 0.0001 ?
    unique_vals = set()
    for ix, j in enumerate(L):
        if j in unique_vals: # this test only avoids rewriting same value
            while j in unique_vals:
                j += delta
            L[ix] = j
        unique_vals.add(j)

两个例程都给出了[0.8963, 0.8964, 0.1234, 0.3456, 0.3457, 0.3458, 0.6789]作为结果。

对于@hashemi在评论([0.001,0.001,0.001,0.002])中给出的示例,这些方法给出了[0.001,0.002,0.003,0.004]