2013-04-10 2 views
1

Я не знаю, как дать точный заголовок, но вот в чем проблема.Объединить два списка с некоторым правилом порядка в python

Проблема:

Я хочу дать ранговый список (представьте, какой топ-лист) с некоторой позиции сохранились уже.

Говорят, у меня есть 7 слотов [1, 2, 3, 4, 5, 6, 7, 8] и некоторые уже сохранили постион 1, 3, 4, 7, 9. (Так как мы имеем только 8 слотов, то perserved ПОлОжЕНИЕ 9 будет значит последний слот.)

Тогда У меня осталось 2, 5, 6 слотов, и я должен заполнить их другими объектами.

Упрощенный вопрос:

У меня есть два списка:

>>> a = [1, 3, 4, 7, 9] 
>>> b = [object_x, object_y, object_z] 

И я хочу, чтобы объединить их в этом:

>>> c = [1, object_x, 3, 4, object_y, object_z, 7, 9] 

(Мы можем взять 'object_x' здесь 0.)

Вот и все, просто хочу посмотреть, есть ли элегантный способ реализовать это.

(. Редактировать весь вопрос, основываясь на комментариях Спасибо, ребята очень много.)

+3

Это действительно неясно, как вы пришли к этому заказу. * 'Сохранить позицию элемента в' *? Что это значит? –

+0

Должны ли они быть объединены в случайном порядке? В этом случае вы можете просто расширить. –

+0

Итак, 'a' всегда будет прогрессией (из 1?) С отсутствующими значениями, которые указаны в' b'? –

ответ

2

Вы можете использовать генератор:

def merge(a, b): 
    b_clone = b[:] 

    for n in range(min(a), max(a) + 1): 
     if n in a: 
      yield n 
     elif b_clone: 
      yield b_clone.pop(0) 
+1

С последним редактированием вопроса, похоже, что 'min (a)' должно быть фактически '1'. –

1

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

def merge(a, b): 
    b = list(b) 
    a = iter(a) 
    current = 1 
    for item in a: 
     while item != current: 
      if b: 
       yield b.pop(0) 
      else: 
       yield item 
       yield from a # <3.3 use `for item in a: yield item` instead. 
       return 
      current += 1 
     yield item 
     current += 1 

Который, кажется, работает в соответствии с вашей спецификации:

>>> print(list(merge([1, 3, 4, 7, 9], [0, 0, 0]))) 
[1, 0, 3, 4, 0, 0, 7, 9] 
>>> print(list(merge([2, 4, 5], [1, 3]))) 
[1, 2, 3, 4, 5] 

Также неясно, что должно произойти, учитывая дополнительные элементы в b - это игнорирует их, но добавление yield from b (или, < 3,3 for item in b: yield item) в конец дал бы им как конечные элементы.

+0

Синтаксис 'yield from' выглядит довольно красиво. – Blender

+0

@Blender Это действительно приятное дополнение. –

0

Это также должно работать:

>>>a = [2, 3, 5, 6, 7, 9] 
>>>b = [0, 0, 0] 
>>>length = len(a) 
>>>i = 0 

>>>while (i < length): 
    if a[i] != i+1: 
     a.insert(i, b.pop(0)) 
     length += 1 
    i += 1 

>>>print(a) 
[0, 2, 3, 0, 5, 6, 7, 0, 9] 
0

Спасибо всем, и я получаю это решение вдохновленного @jurgenreza

>>> a = [1, 3, 4, 7, 9] 
>>> b = [0, 0, 0] 
>>> for i in a: 
     b.insert(i - 1, i) 

>>> print b 
[1, 0, 3, 4, 0, 0, 7, 9] 
0

Вы, возможно, будет лучше избегать того, чтобы сделать это слияние в первом место. Если вы заранее знаете, сколько возможных рангов, вы можете запустить свой список как содержащий столько None, и каждый раз, когда занимаете пробел, установите это, используя назначение списка, а не добавляя.Тогда ваше окончательное слияние так же просто, как:

def merge(a, b): 
    b = iter(b) 
    for i,x in a: 
     if x is None: 
      a[i] = next(b) 

Если бы вы были так склонны, вы могли бы поставить этот whoe структуру данных в класс, который также позволит вам, например, проверить, когда вы пытаетесь перезапишите занятую позицию (если это будет ошибка):

class Ranks: 
    def __init__(self, size): 
     self._list = [None] * size 

    def __getitem__(self, position): 
     return self._list[position] 

    def __setitem__(self, position, val): 
     if self._list[position] is None: 
      raise ValueError('attempting to clobber existing rank data') 
     self._list[position] = val 
Смежные вопросы