簡體   English   中英

如何在Python列表中標識序列的開始和結束?

[英]How to identify the start and the end of a sequence inside a list in Python?

想象一下,您已經完成了依次使用不同樣品材料的實驗。 您已經完成實驗,並且對結果滿意(可能需要嘗試幾次),然后再開始使用其他示例材料,因此序列將依次出現:

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

還引入了另一個列表,該列表被適當地命名為quality以便區分好和壞的度量:

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

在列表推導中應用該規則以使用TrueFalse排除錯誤的度量:

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']

我想找到起點和終點的原因是,我想用它們來確定基於這些數據的其他數據的位置(謝謝您,Matt B.指出我的真實意圖制定得不好。 ):

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中是否有一種優雅的方法?

您可以使用列表理解來做到這一點。

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

等等,等等。

然后,您可以調整理解范圍以根據不同條件構建列表。

試試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']}

我想出了兩種可行的方法,但這可能並不是最好的方法,因為我認為自己是一個新手。 首先,備選方案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

然后,這可以用來完成我在原始問題中描述的其余部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM