Как автоматически увеличить повторяющиеся значения на определенное число в Python? - PullRequest
0 голосов
/ 04 января 2019

Я ожидаю, что список будет отсортирован, а затем дубликаты будут разнесены с шагом 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 голосов
/ 04 января 2019

вот решение по вашему коду.ваш код прав, что вам не хватало, был случай, когда значение my_list[i]+0.1*i уже присутствует.то есть, например, когда 20 там, вы увеличиваете его до 20,1 (происходит), но вы пропускаете это, но когда 20,1 там.вы просто проверяете только на 20, а не на 20.1.вот почему 20.1 приходит в вашем решении, а не 20.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:
        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]
0 голосов
/ 04 января 2019

Другой (более продвинутый) вариант - написать генератор 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)

ИМО, это не самое простое решение. Я делюсь этим в любом случае, потому что это может помочь другим понять генераторы, особенно yield from.

0 голосов
/ 04 января 2019

Использование 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]

Если вам нужно, чтобы исходные значения оставались целыми числами, прокомментируйте ниже, и я изменю это.

0 голосов
/ 04 января 2019

Попробуйте этот улучшенный код:

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)
0 голосов
/ 04 января 2019

Проблема в том, что вы увеличиваете его только один раз.Вы не ведете счет того, сколько раз число появилось раньше.

Вам нужен какой-то частотный словарь, который будет хранить, сколько раз это число появилось.Используя эту частоту 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)
0 голосов
/ 04 января 2019

Я могу предложить простое исправление к исходному коду:

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)
0 голосов
/ 04 января 2019

Вы можете использовать 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...