Как заполнить пробелы в списке кортежей - PullRequest
4 голосов
/ 25 марта 2020

У меня есть список кортежей, подобных следующему:

[(1, 'Red'), (2, 'Yellow'), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]

Числа в кортеже представляют индекс. Однако, поскольку в моем входном файле отсутствуют некоторые индексы, мне нужно вставить несколько кортежей в список и сделать список похожим на следующее:

[(1, 'Red'), (2, 'Yellow'), (3, None), (4, None), (5, None), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]

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

Ответы [ 5 ]

4 голосов
/ 25 марта 2020

Вот простой подход, который вы можете попробовать. Если сначала получить диапазон чисел min и max, затем получить пропущенные числа, используя разность наборов set(A) - set(B), затем объединить пропущенные числа с исходным списком и отсортировать результат с sorted(). Я также добавил комментарии, чтобы объяснить подход:)

lst = [(1, 'Red'), (2, 'Yellow'), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]

# Get only numbers
active_numbers = [x for x, _ in lst]

# Get min and max ranges
min_number, max_number = min(active_numbers), max(active_numbers)

# Get all possible numbers in range
all_numbers = set(range(min_number, max_number + 1))

# Find missing numbers using set difference set(A) - set(B)
difference = all_numbers - set(active_numbers)

# Add missing numbers and original numbers and sort result
result = list(sorted(lst + [(x, None) for x in difference]))

print(result)

Вывод:

[(1, 'Red'), (2, 'Yellow'), (3, None), (4, None), (5, None), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]
3 голосов
/ 25 марта 2020

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

z = [(1, 'Red'), (2, 'Yellow'), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]
d = dict(z)
low, high = min(d), max(d)
result = [(i, d.get(i)) for i in range(low, high + 1)]
2 голосов
/ 25 марта 2020

Вот простой однопроходный метод, который поддерживает порядок оригинала:

out = []
lasti = 0
for i, v in data:
    if i - lasti > 1:
        # if not continued, fix the gap
        for j in range(lasti + 1, i):
            out.append((j, None))
    out.append((i, v)) # add the value
    lasti = i
print(out)

Вывод:

[(1, 'Red'), (2, 'Yellow'), (3, None), (4, None), (5, None), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]
2 голосов
/ 25 марта 2020

Следующий код работал для меня. Это очень наивно и не особенно эффективно. min_key и max_key дают вам интервалы для ваших ключей, поэтому вы не всегда начинаете с 0. Для всех индексов в этом диапазоне будет установлено значение по умолчанию None. Если значение присутствует, ничего не меняется.

Затем элементы в словаре будут отсортированы по значению ключа.

    data = [(1, 'Red'), (2, 'Yellow'), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]
    data_as_dict = dict(data)
    max_key = max(data_as_dict.keys())
    min_key = min(data_as_dict.keys())

    for i in range(min_key, max_key):
        data_as_dict.setdefault(i, None)
    data_as_dict = sorted(data_as_dict.items(), key=lambda item: item[0])
    print(data_as_dict)

[(1, 'Red'), (2, 'Yellow'), (3, None), (4, None), (5, None), (6, 'Pink'), (7, 'Blue'), (8, 'Green')]

Однако, если вы не Не обращая внимания, начиная с индекса 0, вы можете захотеть взглянуть на использование списка, содержащего только ваши цвета, где первое значение вашего кортежа - это индекс внутри списка, для оптимизации использования памяти.

Надеюсь это помогает!

1 голос
/ 25 марта 2020

Я предлагаю здесь простейшую реализацию, но не очень эффективную для больших списков:

test = [(1, 'color: Red'), (2, 'color: Yellow'), (6, 'color: Pink'), (7, 'color: Blue'), (8, 'color: Green')]


max_index = max(test, key=lambda item:item[0])[0]

missing_values = []
for i in range(1, max_index + 1):
    missing = False
    for index, val in test:
        if i != index:
            missing = True
        else:
            missing = False
            break
    if missing:
        missing_values.append((i,'color: None'))

new_test = test + missing_values
new_test_sorted = sorted(new_test, key=lambda x:x[0])
print(new_test_sorted)

Это дает:

[(1, 'color: Red'), (2, 'color: Yellow'), (3, 'color: None'), (4, 'color: None'), (5, 'color: None'), (6, 'color: Pink'), (7, 'color: Blue'), (8, 'color: Green')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...