如何在Python中将重复值自动按特定数字递增?

时间:2019-01-04 10:34:11

标签: python python-3.x algorithm python-2.7 math

我希望对列表进行排序,然后重复项将以0.1的增量间隔。为什么下面的代码不起作用?这是我期望得到的与程序返回的信息:

  

预期输出[11, 15, 15.1, 20, 20.1, 20.2, 20.3, 20.4, 30, 30.1, 40, 40.1, 50, 50.1]

     

实际输出[11, 15, 15.1, 20, 20.1, 20.1, 20.1, 20.1, 30, 30.1, 40, 40.1, 50, 50.1]

Python代码:

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
dup_list = []


for i in range (len(my_list)):
    if my_list[i] not in dup_list:
        dup_list.append(my_list[i])
    else:
        my_list[i] = my_list[i] + 0.10

    dup_list.append(my_list[i])

7 个答案:

答案 0 :(得分:4)

您可以使用itertools.groupby对相等的连续元素进行分组:

from itertools import groupby

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
result = [g + i * 0.1 for k, group in groupby(my_list) for i, g in enumerate(group)]
print(result)

输出

[11.0, 15.0, 15.1, 20.0, 20.1, 20.2, 20.3, 20.4, 30.0, 30.1, 40.0, 40.1, 50.0, 50.1]

答案 1 :(得分:2)

我可以提出对原始代码的简单修复:

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
dup_list = []

for i in range (len(my_list)):
    if my_list[i] not in dup_list:
        dup_list.append(my_list[i])
    else:
        dup_list.append(dup_list[i-1]+0.1)

答案 2 :(得分:1)

问题是您只增加了一次。您没有在计算一个数字出现过多少次。

您需要的是某种频率字典,它将存储该数字出现了多少次。使用该频率f,您可以在数字上添加f-1增量。

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
dup_list = []
feq = {}

for i in range (len(my_list)):
    if my_list[i] not in feq:
        feq[my_list[i]] = 1
    else:
        feq[my_list[i]] += 1

    dup_list.append(my_list[i] + (feq[my_list[i]]-1)*0.1)

答案 3 :(得分:1)

尝试以下改进的代码:

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
out_list = []

for value in my_list:
    if value in out_list:
        while value in out_list:
            value += .1
    out_list.append(value)

答案 4 :(得分:0)

使用defaultdict

from collections import defaultdict

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
dup_list = []
occurrences = defaultdict(int)

for elmt in my_list:
    dup_list.append(elmt + occurrences[elmt] * 0.10)
    occurrences[elmt] += 1

输出:

[11.0, 15.0, 15.1, 20.0, 20.1, 20.2, 20.3, 20.4, 30.0, 30.1, 40.0, 40.1, 50.0, 50.1]

如果您希望原始值仍然是整数,请在下面添加注释,我将其更改。

答案 5 :(得分:0)

这是根据您的代码提供的解决方案。 您的代码是正确的,my_list[i]+0.1*i正是您所缺少的 值已经存在。即在示例中,当有20时将其增加到 20.1(发生),但是您错过了,但是当20.1存在时。你只是检查 仅20个不20.1。这就是为什么您的解决方案中使用的不是20.1而是20.1的原因。

my_list = [20,20,20,30,20,30,40,50,15,11,20,40,50,15]
my_list.sort()
dup_list = []


for i in range (len(my_list)):
    if my_list[i] not in dup_list:
        dup_list.append(my_list[i])
    else:
        j=1
        res = True
        while res:
            val = my_list[i]+j*0.1
            if val  not in dup_list:
                dup_list.append(val)
                res = False
            j+=1 

print(dup_list)

#output [11, 15, 15.1, 20, 20.1, 20.2, 20.3, 20.4, 30, 30.1, 40, 40.1, 50, 50.1]

答案 6 :(得分:0)

另一个(更高级的)选项是编写一个cusom生成器:

from itertools import count

def gen(value):
    """Returns a generator that first yields `value` and then `value + x * 0.10` (where x is 1, 2, ...).
    """
    yield value
    yield from map(lambda x: value + x * 0.10, count(1))

my_list = [20, 20, 20, 30, 20, 30, 40, 50, 15, 11, 20, 40, 50, 15]

# create a generator for each distinct value in my_list
generators = {k: gen(k) for k in set(my_list)}

# calculate the result list
dup_list = [next(generators[elmt]) for elmt in sorted(my_list)]

print(dup_list)

IMO,这不是最简单的解决方案。我仍然分享它,因为它可以帮助其他人理解生成器,尤其是yield from