当一个值发生变化时,Pythonic方法可以在元组上进行迭代

时间:2015-08-03 20:19:43

标签: python list tuples

我有一组数据:

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大于前一个时,有两个边界条件可以工作。

我考虑过简单地使用枚举(数据)并检查先前与当前,但有更多“pythonic”方式吗?

3 个答案:

答案 0 :(得分:3)

只需存储以前的值:

public function processForm(Address $address, Request $request)
{
    /** @var AddressRepository $addressRepository */

    $form = $this->createForm($this->get('address.form_type'), $address);

    $form->submit($request->get($form->getName()));

    if ($form->isValid())
    {
        $addressRepository = $this->get('address.repository');
        $addressRepository->save($address);
        return $this->get('success');
    }
    return $form;
}

或者您可以跟踪唯一的previous = None for H, W, V in data: if previous and previous != W: break # # do something with the values # previous = W 值:

H

或者您可以使用itertools.groupby()对元组中的第二个值进行分组,并仅使用第一个组:

seen = set()

for H, W, V in data:
    if H in seen:
        break
    seen.add(H)
    #
    # do something with the values
    #

答案 1 :(得分:1)

我会使用while循环。像这样:

w_at_start = data[0][1]
index = 0
while data[index][1] == w_at_start:
    # your actions
    index += 1

答案 2 :(得分: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))]