Как определить начало и конец последовательности внутри списка в Python? - PullRequest
0 голосов
/ 11 апреля 2019

Представьте, что вы выполнили эксперименты с использованием различных образцов материалов в последовательности. Вы закончили свои эксперименты, и вы удовлетворены результатами (это может занять несколько попыток), прежде чем вы начнете с другого материала образца, поэтому последовательности будут появляться после друг друга:

list_ex = ['Iron', 'Iron', 'Iron', 'Iron', 'Iron', 'Steel', 'Steel', 'Aluminium', 'Aluminium', 'Aluminium']

Введен еще один список с соответствующим названием quality, чтобы различать хорошие и плохие измерения:

quality = ['BAD', 'BAD', 'BAD', 'GOOD', 'GOOD', 'BAD', 'GOOD', 'BAD', 'GOOD', 'GOOD']

, который применяется в понимании списка для исключения неверных измерений с использованием True и False:

qual = [True if _ == 'GOOD' else False if _ == 'BAD' else False for _ in quality]

Из этого примера вы видите, что одна последовательность материалов следует за другой без пересечения. Тем не менее, я хотел бы классифицировать данные, найдя начало и конец каждой последовательности, чтобы сделать что-то вроде этого:

list_iron  = list_ex[start_iron:end_iron+1]
list_steel = list_ex[start_steel:end_steel+1]
list_alu   = list_ex[start_alu:end_alu+1]

, что даст следующие результаты:

In[1]:  list_iron
Out[1]: ['Iron', 'Iron', 'Iron', 'Iron', 'Iron']

In[2]:  list_steel
Out[2]: ['Steel', 'Steel']

In[3]:  list_alu
Out[3]: ['Aluminium', 'Aluminium', 'Aluminium']

Причина, по которой я хотел бы найти начало и конец, заключается в том, что я хотел бы использовать их для определения позиции других данных, которые основаны на них (спасибо, Мэтт Б., за указание на то, что мои истинные намерения были плохо сформулированы):

In[4]:  freq_steel = frequency[start_steel:end_steel+1]
In[5]:  freq_steel
Out[5]: [[100, 200, 300, 400, 500], [1000, 2000, 3000, 4000, 5000]]

Но поскольку одно из стальных измерений было плохим, в идеале я бы хотел:

In[6]:  qual_steel = quality[start_steel:end_steel+1]
In[7]:  qual_steel
Out[7]: [False, True]
In[8]:  freq_steel[qual_steel]
Out[8]: [1000, 2000, 3000, 4000, 5000]
  • Есть ли элегантный способ сделать это в Python?

Ответы [ 3 ]

1 голос
/ 11 апреля 2019

Попробуйте itertools.groupby:

>>> import itertools
>>> [list(v) for _, v in itertools.groupby(list_ex)]
[['Iron', 'Iron', 'Iron', 'Iron', 'Iron'], ['Steel', 'Steel'], ['Aluminium', 'Aluminium', 'Aluminium']]
>>> {k: list(v) for k, v in itertools.groupby(list_ex)}
{'Iron': ['Iron', 'Iron', 'Iron', 'Iron', 'Iron'], 'Steel': ['Steel', 'Steel'], 'Aluminium': ['Aluminium', 'Aluminium', 'Aluminium']}
1 голос
/ 11 апреля 2019

Вы можете использовать списочное понимание, чтобы сделать это;

list_iron = [item for item in list_ex if item == 'Iron']
list_steel = [item for item in list_ex if item == 'Steel']

И так далее, и тому подобное.

И затем вы можете адаптировать понимание для построения списков по различным критериям.

0 голосов
/ 16 апреля 2019

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

def finder(lst, condition):
    return [a for a, b in enumerate(lst) if condition(b)]

iron  = finder(Material, lambda _: _ == 'Iron')
steel = finder(Material, lambda _: _ == 'Steel')
alu   = finder(Material, lambda _: _ == 'Aluminium')

start_iron  = iron[0]
end_iron    = iron[-1]
start_steel = steel[0]
end_steel   = steel[-1]
start_alu   = alu[0]
end_alu     = alu[-1]

Во-вторых, альтернатива B:

iron  = [_ for _ in Material if _ == 'Iron']
steel = [_ for _ in Material if _ == 'Steel']
alu   = [_ for _ in Material if _ == 'Aluminium']

n_iron  = len(iron)
n_steel = len(steel)
n_alu   = len(alu)

start_iron  = 0
end_iron    = n_iron
start_steel = end_iron
end_steel   = start_steel + n_steel
start_alu   = end_steel
end_alu     = start_alu + n_alu

Затем она может, в свою очередь, использоваться для выполнения всего остального, что я описал в первоначальном вопросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...