[英]Remove both adjacent tuples from lists
鑒於此列表:
[(1, 's'), (2, 'e'), (2, 's'), (3, 'e')]
這是可能重疊的時間間隔的表示,例如1 --> 2
和2 --> 3
,為了便於處理,我將其引入了該表示(有關上下文,請參見此答案 )
我想刪除對(2, 'e')
- (2, 's')
因為一個間隔的結尾( e
)與下一個間隔的開始( s
)處於相同的數字( 2
)間隔。 所以結果應該是
[(1, 's'), (3, 'e')]
並且代表1 --> 3
。
編輯 :也有可能間隔是重疊的,例如1-->4
和2-->3
。 這將在此元組列表中表示(請注意該列表已排序): [(1, 's'), (2, 's'), (3, 'e'), (4, 'e')]
。 在這種情況下,無需做任何事情,因為沒有兩個元組共享相同的數字。
我想出了這個減少:
import functools
functools.reduce(lambda l,i: l[:-1] if i[0] == l[-1][0] and i[1] != l[-1][1] else l + [i], a[1:], [a[0]])
有更好的方法來實現這一目標嗎?
您可以使用itertools.groupby
稍長一點(兩行),盡管解決方案更具可讀性:
import itertools
def get_combinations(s):
new_data = [(a, list(b)) for a, b in itertools.groupby(s, key=lambda x:x[0])]
return [b[-1] for i, [a, b] in enumerate(new_data) if len(b) == 1 or len(b) > 1 and i == len(new_data) - 1]
print(get_combinations([(1, 's'), (2, 'e'), (2, 's'), (2, 'e')]))
print(get_combinations([(1, 's'), (2, 'e'), (2, 's'), (3, 'e')]))
輸出:
[(1, 's'), (2, 'e')]
[(1, 's'), (3, 'e')]
最近我一直在使用函數式語言,所以它讀到的Python語言可能比某些語言少,但我會使用(修改過的) itertools
的pairwise
配方逐對迭代
def pairwise(iterable):
a, b = itertools.tee(iterable)
next(b, None) # advance the second iterator
return itertools.zip_longest(a, b, fillvalue=(None, None))
然后過濾哪些對不匹配:
def my_filter(a, b):
a_idx, a_type = a
b_idx, b_type = b
if a_idx == b_idx and a_type == "e" and b_type == "s":
return False
return True
自己過濾它們(因為幼稚的filter
將允許“開始”值存在,因為它與前面的元素配對)
def filter_them(some_list):
pairs = pairwise(some_list)
acc = []
while True:
try:
a, b = next(pairs)
if my_filter(a, b):
acc.append(a)
else:
next(pairs) # skip the next pair
except StopIteration:
break
return acc
我在考慮“雙重繼續”方法,並提出了這個生成器解決方案:
def remove_adjacent(l):
iterator = enumerate(l[:-1])
for i, el in iterator:
if el[0] == l[i+1][0] and el[1] != l[i+1][1]:
next(iterator)
continue
yield el
yield l[-1]
您可以輕松地做到這一點,只需讓2個臨時變量1循環並檢查是否為if。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.