найдите уникальные индексы из списка

#python #list #python-2.7

#python #Список #python-2.7

Вопрос:

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

 a = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [4,4]
  

и список также может быть таким

 a = [1, 1, 1, 4, 1, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [1,4]
  

и мне нужна позиция индекса в списке a для значения, которое есть в списке b

Мой ожидаемый результат должен (это позиция индекса значения)

 output- 
 1. [0,1]
 
 2. [0,3] 
  

Этот код выдает все значения индекса там, где они совпадают

 c_set = set() 
res = [] 
for idx, val in enumerate(test_list): 
    if val not in oc_set: 
        oc_set.add(val)          
    else: 
        res.append(idx) 
  

но мне нужна длина значения индекса в виде списка b, как я упоминал в моем ожидаемом выводе.

Заранее спасибо

Комментарии:

1. Я подозреваю, что set() подход нарушен для вашего первого примера, потому что у вас есть [4, 4] , поэтому второй экземпляр 4 будет проигнорирован. Мне непонятно, почему это должно давать [0, 1] вместо [0, 0] — это определенно ожидаемое поведение?

2. Я не могу понять вашу проблему, не могли бы вы объяснить подробно

3. Вывод не суммируется, что представляют эти индексы?

4. По какой-то причине вы даете два значения для a и для b каждого в верхней части вашего вопроса, а затем вы даете ожидаемые результаты для, предположительно, одного из этих случаев …? Какие версии a и b связаны ли они с двумя?

5. @ roganjosh Потому что, как вы можете видеть в моем списке b, есть два значения, и я хочу два разных индекса для этих значений.

Ответ №1:

Я не вижу особой надежды на использование index() здесь, потому что ваш первый пример даст [0, 0] , поскольку он всегда возвращает индекс первого экземпляра (если он существует). Вместо этого мы можем перемещаться по a и постепенно сокращать список для поиска. Для каждого нового фрагмента мы увеличиваем offset , чтобы мы знали, какую часть списка мы теряем каждый раз, когда цель найдена.

Мы также можем выполнить однократное преобразование списка для поиска в набор, для проверки O (1), действительно ли элемент для поиска существует в списке.

 def find(search, targets):
    
    peek = set(search)
    
    res = []
    offset = 0
    for target in targets:
        if target not in peek:
            res.append(None)
            continue
            
        for i, value in enumerate(search):
            if value == target:
                res.append(i   offset)
                offset  = i   1
                search = search[offset:]
                break
    return res

a = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [4,4]
print(find(a, b))

a = [1, 1, 1, 4, 1, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [1,4]

print(find(a, b))

a = [1, 1, 1, 4, 1, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [1, 9, 4]

print(find(a, b))
  

Ответ №2:

Немного не так, но работает:

 results = [None]*len(b)
for a_index, a_elem in enumerate(a):
    for b_index, b_elem in enumerate(b):
        if a_elem==b_elem and results[b_index]==None:
            results[b_index] = a_index
            a_elem = str(a_elem)
results
  

Выдает следующие результаты:

  1. [0,1]

  2. [0,3]

Это работает даже в том случае, если вам нужно узнать последний соответствующий индекс вместо первого, с небольшой поправкой:

 results = [None]*len(b)
for a_index, a_elem in enumerate(a):
    for b_index, b_elem in enumerate(b):
        if a_elem==b_elem :#and results[b_index]==None:
            results[b_index] = a_index
            a_elem = str(a_elem)
results
  

Ответ №3:

Работает ли это? try Охватывает случай, когда значение в b отсутствует в a , что добавило бы None к выводу

 indices = []
for val in b:
    try:
        idx = a.index(val)
        indices.append(idx)
        a[idx] = None
    except:
        indices.append(None)
  

Результаты: [0, 1] и [0, 3]

РЕДАКТИРОВАТЬ: @Chris указал, что использование None является лучшим подходом

Комментарии:

1. @Крис хороший улов, в последнее время слишком увлекся numpy @.@ и автоматически пошел на это в надежде на эффективность. Подумав об этом, a.index(val) может быть быстрее, так как он уже находится в O (n)

2. Спасибо Вам за этот простой подход 🙂

Ответ №4:

Исходя из моего понимания проблемы:

 a = [1, 1, 1, 4, 1, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [9,4]

[a.index(x) if x in a else None for x in b]
  

Выходной сигнал:

 [None, 3]
  

Комментарии:

1. Попробуйте это с первым примером. Это дает [0, 0] . Это не работает

Ответ №5:

Я думаю, что этот подход более прост, чем другие. Хотя и не уверен в его производительности.

 a = [1, 1, 1, 4, 1, 0, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0]
b = [1,4]
resp = []


def find_from_a(idx):
    for i, v in enumerate(a, start=idx):
        yield i, v


last_idx = 0
for lookup_val in b:
    for found_idx, found_val in find_from_a(idx=last_idx):
        if found_val == lookup_val:
            resp.append(found_idx)
            last_idx = found_idx
            break

print(resp)
  

Если вам всегда нужно начинать с начала, просто удалите last_idx переменную и сделайте так, чтобы она всегда начиналась с начала.