Поиск индекса первого вхождения любого элемента в списке

Mac OS X

В Mac OS X вы можете использовать Automator для создания приложения, которое вызывает ваше приложение python и передает путь входного файла в виде строкового аргумента. В мастере рабочего процесса приложения добавьте действие «Запустить сценарий оболочки», выберите Pass input: как as arguments, а в текстовом поле добавить:

python /path/to/my/app/myapp.py "$@"

"$@" проходит по всем аргументам в вход (как выбранный файл) в виде строк. Пока ваш скрипт настроен для работы с вводом (sys.argv) в виде списка строк (первый из которых является путём приложения python), тогда он будет работать.

Когда вы сохраняете этот Рабочий процесс Automator обрабатывается OS X, как и любое другое приложение, и вы можете установить это приложение как значение по умолчанию для файлов типа «* .foo». Чтобы связать «* .foo» с этим приложением, щелкните правой кнопкой мыши файл .foo, Get Info, Open with: Other..., выберите приложение, которое вы создали в Automator, затем нажмите кнопку Change All....

Windows

Подобный, но, надеюсь, менее привлекательный подход может работать в Windows. Вероятно, вы можете создать командный файл (.bat) со следующим:

python C:\path\to\my\app\myapp.py %*

%* расширяется ко всем аргументам.

Пока вы можете связать файл расширение с этим пакетным файлом, тогда вы можете это сделать, и это ваше решение. Однако я не пробовал это решение для Windows, поэтому возьмите его с солью. Решение Mac, с другой стороны, я проверил.

-2
задан innuendo 13 July 2018 в 10:20
поделиться

4 ответа

Поверните список в набор, затем используйте .index:

output = [my_list.index(elem) for elem in set(my_list)]

Так как set неупорядочен, вы можете отсортировать вывод:

output = sorted(my_list.index(elem) for elem in set(my_list))

Full пример:

>>> my_list = ['hi', 'babe', 'hi', 'babe', 'key', 'key']         
>>> output = sorted(my_list.index(elem) for elem in set(my_list))
>>> output                                                       
[0, 1, 4]   
2
ответ дан DeepSpace 17 August 2018 в 13:20
поделиться
  • 1
    Конечно, это будет иметь сложность O (n²) ... – tobias_k 13 July 2018 в 08:50
  • 2
    @tobias_k ... Вероятно, сортировка не нужна. Итак, [4, 0, 1] в порядке. Поскольку мне нужно будет использовать idx для выбора элементов из my_list и некоторых других данных. Чтобы сделать это для my_list, я использовал: pandas ... my_list = pd.Series (my_list); my_list = my_list.get (вывод); ... не уверен, что это лучший способ сделать это? И спасибо за ваш вклад в любом случае! – innuendo 13 July 2018 в 10:39
  • 3
    @innuendo Ну, это отличный пример проблемы XY. Вы должны были упомянуть, что ваши данные находятся в фрейме данных. pandas предлагают векторизованные операции, которые могут достичь того, что вы ищете намного быстрее, чем любой цикл Python может достичь – DeepSpace 13 July 2018 в 10:41
  • 4
    @DeepSpace .. Поскольку я немного новичок в Python и по-прежнему отмечен менталитетом C ++, я все еще не уверен, есть ли функция panda, которая дает предполагаемый выход .output = [0, 1, 4] или даже [ 4, 0, 1]. – innuendo 13 July 2018 в 10:50
  • 5
    @innuendo Сортировка здесь не проблема, но повторные вызовы index. – tobias_k 13 July 2018 в 11:19

Вы также можете собирать индексы в словаре, где записано только первое появление каждого элемента:

from collections import OrderedDict

my_list = ['hi', 'babe', 'hi', 'babe', 'key', 'key']

d = OrderedDict()
for i, item in enumerate(my_list):
    d.setdefault(item, i)

print([d[k] for k in d])
# [0, 1, 4]

A collections.OrderedDict() используется для поддержания порядка вставки.

2
ответ дан RoadRunner 17 August 2018 в 13:20
поделиться
  • 1
    Почему список? Как насчет только d.setdefault(item, i)? – tobias_k 13 July 2018 в 09:33
  • 2
    @tobias_k Много умнее, обновил мой ответ. Я также быстро понял, что список просто бессмыслен. – RoadRunner 13 July 2018 в 09:43

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

>>> seen = set()
>>> [int(not(s in seen or seen.add(s))) for s in my_list]
[1, 1, 0, 0, 1, 0]
>>> [i for i, e in enumerate(_) if e]
[0, 1, 4]
2
ответ дан tobias_k 17 August 2018 в 13:20
поделиться

Список имеет встроенную функцию .index:

my_list = ['hi', 'babe', 'hi', 'babe', 'key', 'key']
my_list.index('hi')
>>>0

.index выполняет поиск по списку, пока не найдет совпадение и не остановится. Если вам понадобятся индексы большего количества совпадений, вы должны использовать понимание списка. Во-первых, вам может понадобиться преобразовать текст в цифры (списки чисел не нужны), например, hi = 0, babe = 1 и т. Д. Это должно быть сделано (может быть, лучше):

unique_words_list = []
number_list = []
for word in my_list:
    if word not in unique_words_list:
    unique_words_list.append(word)
for i in range(len(my_list)):
    for j in range(len(unique_words_list)):
        if my_list[i]==unique_words_list[j]:
            number_list.append(j)


unique_words_list, number_list    
>>>(['hi', 'babe', 'key'], [0, 1, 0, 1, 2, 2])    

Тогда ваше понимание списка:

[i for i, e in enumerate(number_list) if e == 1]
>>>[1,3]

Это означает, что у вас есть «младенец» на 1-й и 3-й позиции в вашем списке.

Возможно, это будет проще! Надеюсь, это поможет.

0
ответ дан Yoana G 17 August 2018 в 13:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: