нарезать список до заданного элемента

#python #arrays #python-3.x #list

#python #массивы #python-3.x #Список

Вопрос:

Если у вас есть список my_list = ['a', 'd', 'e', 'c', 'b', 'f'] , и вы хотите создать подсписок, содержащий все элементы вплоть до заданного, например my_list_up_to_c = ['a', 'd', 'e'] , как это можно сделать таким образом, чтобы это было легко масштабируемо? Также это можно сделать быстрее, используя массивы numpy?

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

1. my_list[:my_list.index(2)] Я думаю. Это должно быть похоже на цикл списка один раз, возвращая в первом экземпляре значение поиска. В худшем случае должно быть O (n)

Ответ №1:

Вероятно, будет использоваться наименьший объем кода .index() (обратите внимание, что этот поиск выполняется до первого появления элемента в указанном списке):

 >>> my_list = ['a', 'd', 'e', 'c', 'b', 'f']
>>> my_list
['a', 'd', 'e', 'c', 'b', 'f']
>>> my_list[:my_list.index('c')]          # excluding the specified element
['a', 'd', 'e']
>>> my_list[:my_list.index('c') 1]        # including the specified element
['a', 'd', 'e', 'c']
  

Временная сложность вызова .index() равна O(n) , что означает, что он будет выполняться не более одного раза по списку. Нарезка списка имеет сложность O(k) (согласно этому источнику), что означает, что это зависит от размера фрагмента.

Таким образом, в худшем случае элемент, который вы ищете, находится в конце списка, поэтому ваш поиск будет выполняться до конца списка ( O(n) ), и фрагмент также скопирует весь список (также O(n) ), что приводит к наихудшему случаю O(2n) , который по-прежнему имеет линейную сложность.

Ответ №2:

Используйте index(), чтобы получить первое вхождение элемента списка. Затем используйте нотацию среза, чтобы получить желаемую часть списка.

 >>> my_list = ['a', 'd', 'e', 'c', 'b', 'f']
>>> my_list[:my_list.index('c')]
['a', 'd', 'e']
  

Ответ №3:

Решение itertools

 In[9]: from itertools import takewhile
In[10]: my_list = ['a', 'd', 'e', 'c', 'b', 'f'] 
In[11]: list(takewhile(lambda x: x != 'c', my_list))
Out[11]: ['a', 'd', 'e']
  

В Haskell это было бы

 takeWhile ((/=) 'c') "adecbf"
  

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

1. Обратите внимание, что это не позволяет включить указанный элемент в результирующий список. Возможно, это то, чего хотел OP, но стоит указать на это ограничение.