2016-09-07 2 views
2

В Python, у меня есть список списокPython найти и заменить последнее появление в списке

list3 = ['PA0', 'PA1'] 
list2 = ['PB0', 'PB1'] 
list1 = ['PC0', 'PC1', 'PC2'] 

[(list1[i], list2[j], list3[k]) for i in xrange(len(list1)) for j in xrange(len(list2)) for k in xrange(len(list3))] 

#Result 
[('PC0', 'PB0', 'PA0'), 
('PC0', 'PB0', 'PA1'), 
('PC0', 'PB1', 'PA0'), 
('PC0', 'PB1', 'PA1'), 
('PC1', 'PB0', 'PA0'), 
('PC1', 'PB0', 'PA1'), 
('PC1', 'PB1', 'PA0'), 
('PC1', 'PB1', 'PA1'), 
('PC2', 'PB0', 'PA0'), 
('PC2', 'PB0', 'PA1'), 
('PC2', 'PB1', 'PA0'), 
('PC2', 'PB1', 'PA1')] 

Как я могу найти последнее появление и добавьте E в качестве суффикса

 
[('PC0', 'PB0', 'PA0'), 
('PC0', 'PB0', 'PA1'), 
('PC0', 'PB1', 'PA0'), 
('PC0E', 'PB1', 'PA1'), 
('PC1', 'PB0', 'PA0'), 
('PC1', 'PB0', 'PA1'), 
('PC1', 'PB1', 'PA0'), 
('PC1E', 'PB1', 'PA1'), 
('PC2', 'PB0', 'PA0'), 
('PC2', 'PB0E', 'PA1'), 
('PC2', 'PB1', 'PA0E'), 
('PC2E', 'PB1E', 'PA1E')] 
+1

всегда сортируется список входов? –

+0

Да, он уже отсортирован как пример –

+0

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

ответ

2

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

seensets = [set() for _ in inputlist[0]] 
outputlist = [] 
for entry in reversed(inputlist): 
    newentry = [] 
    for value, seen in zip(entry, seensets): 
     newentry.append(value + 'E' if value not in seen else value) 
     seen.add(value) 
    outputlist.append(tuple(newentry)) 
outputlist.reverse() 

Демо:

>>> seensets = [set() for _ in inputlist[0]] 
>>> outputlist = [] 
>>> for entry in reversed(inputlist): 
...  newentry = [] 
...  for value, seen in zip(entry, seensets): 
...   newentry.append(value + 'E' if value not in seen else value) 
...   seen.add(value) 
...  outputlist.append(tuple(newentry)) 
... 
>>> outputlist.reverse() 
>>> pprint(outputlist) 
[('PC0', 'PB0', 'PA0'), 
('PC0', 'PB0', 'PA1'), 
('PC0', 'PB1', 'PA0'), 
('PC0E', 'PB1', 'PA1'), 
('PC1', 'PB0', 'PA0'), 
('PC1', 'PB0', 'PA1'), 
('PC1', 'PB1', 'PA0'), 
('PC1E', 'PB1', 'PA1'), 
('PC2', 'PB0', 'PA0'), 
('PC2', 'PB0E', 'PA1'), 
('PC2', 'PB1', 'PA0E'), 
('PC2E', 'PB1E', 'PA1E')] 
+1

Пока вы все равно используете 'list', возможно, измените последнюю строку из' outputlist = outputlist [:: - 1] 'на' outputlist.reverse() ', чтобы выполнить разворот вместо того, чтобы создавать новую, отменил «список» и выбросил старый? – ShadowRanger

+0

@ShadowRanger: duh, да, намного лучше .. –

+0

Wao, он отлично работал. Большое спасибо –

1

Если вы не гонитесь за скоростью молнии здесь, вы можете сделать следующее:

  1. Flatten список с использованием https://stackoverflow.com/a/952952/2988730
  2. Найти уникальные элементы
  3. Найти индекс последнего вхождения каждого уникального элемента (путем изменения списка)
  4. Update элемент
  5. Переформуйте сплющенный список назад с помощью https://stackoverflow.com/a/10124783/2988730

Вот это пример реализации:

# 1 
flat = list(reversed([x for group in mylist for x in group])) 
# 2 
uniq = set(flat) 
# 3, 4 
for x in uniq: 
    flat[flat.index(x)] += 'E' 
# 5 
mylist = list(zip(*[reversed(flat)]*3)) 

Результат:

[('PC0', 'PB0', 'PA0'), 
('PC0', 'PB0', 'PA1'), 
('PC0', 'PB1', 'PA0'), 
('PC0E', 'PB1', 'PA1'), 
('PC1', 'PB0', 'PA0'), 
('PC1', 'PB0', 'PA1'), 
('PC1', 'PB1', 'PA0'), 
('PC1E', 'PB1', 'PA1'), 
('PC2', 'PB0', 'PA0'), 
('PC2', 'PB0E', 'PA1'), 
('PC2', 'PB1', 'PA0E'), 
('PC2E', 'PB1E', 'PA1E')] 
1

Аноф эр подход, который собирает продолжает добавлять индексы, так что вы в конечном итоге с индексами для последнего вхождения, itertools.product также создать первоначальный список для вас:

from itertools import product 

def last_inds(prod): 
    # the key/value will be overwritten so we always keep the last seen 
    return {ele: (i1, i2) for i1, prod in enumerate(prod) for i2, ele in enumerate(prod)} 

prod = list(product(*(list1, list2, list3))) 

# use the indexes to change the last occurrences. 
for r, c in last_inds(prod).values(): 
    lst = list(prod[r]) 
    lst[c] += "E" 
    prod[r] = tuple(lst) 

Который дает ожидаемый результат:

[('PC0', 'PB0', 'PA0'), 
('PC0', 'PB0', 'PA1'), 
('PC0', 'PB1', 'PA0'), 
('PC0E', 'PB1', 'PA1'), 
('PC1', 'PB0', 'PA0'), 
('PC1', 'PB0', 'PA1'), 
('PC1', 'PB1', 'PA0'), 
('PC1E', 'PB1', 'PA1'), 
('PC2', 'PB0', 'PA0'), 
('PC2', 'PB0E', 'PA1'), 
('PC2', 'PB1', 'PA0E'), 
('PC2E', 'PB1E', 'PA1E')] 

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

In [37]: %%timeit 
prod = list(product(*(list1, list2, list3))) 
m(prod) 
    ....: 
10000 loops, best of 3: 20.7 µs per loop 

In [38]: %%timeit 
prod = list(product(*(list1, list2, list3))) 
for r, c in last_inds(prod).values(): 
    lst = list(prod[r]) 
    lst[c] += "E" 
    prod[r] = tuple(lst) 
    ....: 

100000 loops, best of 3: 12.2 µs per loop 

где т:

def m(inputlist): 
    seensets = [set() for _ in inputlist[0]] 
    outputlist = [] 
    for entry in reversed(inputlist): 
     newentry = [] 
     for value, seen in zip(entry, seensets): 
      newentry.append(value + 'E' if value not in seen else value) 
      seen.add(value) 
     outputlist.append(tuple(newentry)) 
    outputlist.reverse() 
Смежные вопросы