当一个值发生变化时,用 Pythonic 方式跳出元组迭代
Pythonic way to break out of iteration over tuples when one value changes
我有一组数据:
H W V
5 1 9.8385465
10 1 8.2087544
15 1 7.8788187
20 1 7.5751283
5 2 5.1217867
10 2 4.3865578
15 2 4.4089918
20 2 4.0254478
这已经被读入元组列表,称之为数据。
我想创建第二个列表,其中包含 H 的值,直到第一次重复,即完成时 H = [5,10,15,20]。有两个边界条件可以工作,当前 H 小于前一个,或者当前 W 大于前一个。
我考虑过简单地使用 enumerate(data) 并检查以前的与当前的,但是有更多 "pythonic" 的方法吗?
只存储之前的值:
previous = None
for H, W, V in data:
if previous and previous != W:
break
#
# do something with the values
#
previous = W
或者您可以跟踪唯一的 H
值:
seen = set()
for H, W, V in data:
if H in seen:
break
seen.add(H)
#
# do something with the values
#
或者您可以使用 itertools.groupby()
对元组中的第二个值进行分组,并且只使用第一组:
from itertools import groupby
from operator import itemgetter
group = next(groupby(data, itemgetter(1)))[1]
for H, W, V in group:
# do something with the values
我会使用 while 循环。像这样:
w_at_start = data[0][1]
index = 0
while data[index][1] == w_at_start:
# your actions
index += 1
您可以使用 itertools.takewhile
:
data = [
(5, 1, 9.8385465),
(10, 1, 8.2087544),
(15, 1, 7.8788187),
(20, 1, 7.5751283),
(5, 2, 5.1217867),
(10, 2, 4.3865578),
(15, 2, 4.4089918),
(20, 2, 4.0254478),
]
from itertools import takewhile, izip
print [data[0][0]] +[
y[0] for x, y in takewhile(
lambda _: _[0][0] <= _[1][0] and _[0][1] >= _[1][1],
izip(data, data[1:])
)
]
结果:
[5, 10, 15, 20]
编辑
更具可读性的版本:
from itertools import takewhile, izip, tee
data = ...
def criterion(_):
prev, curr = _
return prev[0] <= curr[0] and prev[1] >= curr[1]
it1, it2 = tee(iter(data))
print [next(it2)[0]] + [y[0] for x, y in takewhile(criterion, izip(it1, it2))]
我有一组数据:
H W V
5 1 9.8385465
10 1 8.2087544
15 1 7.8788187
20 1 7.5751283
5 2 5.1217867
10 2 4.3865578
15 2 4.4089918
20 2 4.0254478
这已经被读入元组列表,称之为数据。 我想创建第二个列表,其中包含 H 的值,直到第一次重复,即完成时 H = [5,10,15,20]。有两个边界条件可以工作,当前 H 小于前一个,或者当前 W 大于前一个。
我考虑过简单地使用 enumerate(data) 并检查以前的与当前的,但是有更多 "pythonic" 的方法吗?
只存储之前的值:
previous = None
for H, W, V in data:
if previous and previous != W:
break
#
# do something with the values
#
previous = W
或者您可以跟踪唯一的 H
值:
seen = set()
for H, W, V in data:
if H in seen:
break
seen.add(H)
#
# do something with the values
#
或者您可以使用 itertools.groupby()
对元组中的第二个值进行分组,并且只使用第一组:
from itertools import groupby
from operator import itemgetter
group = next(groupby(data, itemgetter(1)))[1]
for H, W, V in group:
# do something with the values
我会使用 while 循环。像这样:
w_at_start = data[0][1]
index = 0
while data[index][1] == w_at_start:
# your actions
index += 1
您可以使用 itertools.takewhile
:
data = [
(5, 1, 9.8385465),
(10, 1, 8.2087544),
(15, 1, 7.8788187),
(20, 1, 7.5751283),
(5, 2, 5.1217867),
(10, 2, 4.3865578),
(15, 2, 4.4089918),
(20, 2, 4.0254478),
]
from itertools import takewhile, izip
print [data[0][0]] +[
y[0] for x, y in takewhile(
lambda _: _[0][0] <= _[1][0] and _[0][1] >= _[1][1],
izip(data, data[1:])
)
]
结果:
[5, 10, 15, 20]
编辑
更具可读性的版本:
from itertools import takewhile, izip, tee
data = ...
def criterion(_):
prev, curr = _
return prev[0] <= curr[0] and prev[1] >= curr[1]
it1, it2 = tee(iter(data))
print [next(it2)[0]] + [y[0] for x, y in takewhile(criterion, izip(it1, it2))]