Python:查找列表对的一个成员中的连续变化,报告其他成员

发布于 2024-09-17 10:33:18 字数 625 浏览 5 评论 0原文

必须有一种更简单、更Python 的方法来做到这一点。

给定这个对列表:

pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]

如何最轻松地找到相邻对中第二个项目发生变化的第一个项目(此处从 1 到 2)。因此我正在寻找 ['c','d']。假设整个列表的pair[1]中只有一个变化,但它可能是一个字符串。

这段代码可以工作,但看起来非常长且麻烦。

for i, pair in enumerate(pp):
    if i == 0: 
        pInitial = pair[0] 
        sgInitial = pair[1]
    pNext = pair[0]
    sgNext = pair[1]
    if sgInitial == sgNext:
        sgInitial = sgNext
        pInitial = pNext
    else:
        pOne = pInitial
        pTwo = pNext
        x = [pOne, pTwo]
        print x
        break

谢谢 蒂姆

There must be a simpler, more pythonic way of doing this.

Given this list of pairs:

pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]

How do I most easily find the first item in adjacent pairs where the second item changes (here, from 1 to 2). Thus I'm looking for ['c','d']. Assume there will only be one change in pair[1] for the entire list, but that it may be a string.

This code works but seems excruciatingly long and cumbersome.

for i, pair in enumerate(pp):
    if i == 0: 
        pInitial = pair[0] 
        sgInitial = pair[1]
    pNext = pair[0]
    sgNext = pair[1]
    if sgInitial == sgNext:
        sgInitial = sgNext
        pInitial = pNext
    else:
        pOne = pInitial
        pTwo = pNext
        x = [pOne, pTwo]
        print x
        break

Thanks
Tim

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

殊姿 2024-09-24 10:33:18
import itertools as it

pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]

# with normal zip and slicing
for a,b in zip(pp,pp[1:]):
    if a[1] != b[1]:
        x=(a[0],b[0])
        print x
        break
# with generators and izip
iterfirst = (b for a,b in pp)
itersecond = (b for a,b in pp[1:])
iterfirstsymbol = (a for a,b in pp)
itersecondsymbol = (a for a,b in pp[1:])
iteranswer = it.izip(iterfirstsymbol, itersecondsymbol, iterfirst, itersecond)

print next((symbol1, symbol2)
           for symbol1,symbol2, first, second in iteranswer
           if first != second)

添加了我的可读生成器版本。

import itertools as it

pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]

# with normal zip and slicing
for a,b in zip(pp,pp[1:]):
    if a[1] != b[1]:
        x=(a[0],b[0])
        print x
        break
# with generators and izip
iterfirst = (b for a,b in pp)
itersecond = (b for a,b in pp[1:])
iterfirstsymbol = (a for a,b in pp)
itersecondsymbol = (a for a,b in pp[1:])
iteranswer = it.izip(iterfirstsymbol, itersecondsymbol, iterfirst, itersecond)

print next((symbol1, symbol2)
           for symbol1,symbol2, first, second in iteranswer
           if first != second)

Added my readable generator version.

对你而言 2024-09-24 10:33:18

您可以尝试类似的方法:(

[[pp[i][0],pp[i+1][0]] for i in xrange(len(pp)-1) if pp[i][1]!=pp[i+1][1]][0]

使用列表理解)

You could try somethingl like :

[[pp[i][0],pp[i+1][0]] for i in xrange(len(pp)-1) if pp[i][1]!=pp[i+1][1]][0]

(using list comprehension)

羁〃客ぐ 2024-09-24 10:33:18

尝试将 pp[:-1]pp[1:] 进行比较,例如

[a for a in zip(pp[:-1], pp[1:]) if a[0][1] != a[1][1]]

(查看 zip(pp[:-1], pp[1: ]) 首先看看

编辑发生了什么:

我想你需要

([a[0][0], a[1][0]] for a in zip(pp[:-1], pp[1:]) if a[0][1] != a[1][1]).next()

try comparing pp[:-1] to pp[1:], something like

[a for a in zip(pp[:-1], pp[1:]) if a[0][1] != a[1][1]]

(look at zip(pp[:-1], pp[1:]) first to see what's going on

edit:

i guess you'd need

([a[0][0], a[1][0]] for a in zip(pp[:-1], pp[1:]) if a[0][1] != a[1][1]).next()
爱你是孤单的心事 2024-09-24 10:33:18
>>> import itertools
>>> pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
>>> gb = itertools.groupby(pp, key=lambda x: x[1])
>>> f = lambda x: list(next(gb)[1])[x][0]
>>> f(-1), f(0)
('c', 'd')
>>> import itertools
>>> pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
>>> gb = itertools.groupby(pp, key=lambda x: x[1])
>>> f = lambda x: list(next(gb)[1])[x][0]
>>> f(-1), f(0)
('c', 'd')
七颜 2024-09-24 10:33:18

这是递归的东西(简单?):

def first_diff( seq, key=lambda x:x ):
    """ returns the first items a,b of `seq` with `key(a) != key(b)` """
    it = iter(seq)
    def test(last): # recursive function
        cur = next(it)
        if key(last) != key(cur):
            return last, cur
        else:
            return test(cur)
    return test(next(it))

print first_diff( pp, key=lambda x:x[1]) # (('c', 1), ('d', 2))

Here is something (simple?) with recursion:

def first_diff( seq, key=lambda x:x ):
    """ returns the first items a,b of `seq` with `key(a) != key(b)` """
    it = iter(seq)
    def test(last): # recursive function
        cur = next(it)
        if key(last) != key(cur):
            return last, cur
        else:
            return test(cur)
    return test(next(it))

print first_diff( pp, key=lambda x:x[1]) # (('c', 1), ('d', 2))
皇甫轩 2024-09-24 10:33:18
pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
def find_first(pp):
    for i,(a,b) in enumerate(pp):
        if i == 0: oldb = b
        else:
            if b != oldb: return i
    return None
print find_first(pp)
pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
def find_first(pp):
    for i,(a,b) in enumerate(pp):
        if i == 0: oldb = b
        else:
            if b != oldb: return i
    return None
print find_first(pp)
百思不得你姐 2024-09-24 10:33:18
>>> pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
>>> [[t1, t2] for ((t1, v1), (t2, v2)) in zip(pp, pp[1:]) if v1 != v2] [0]
['c', 'd']
>>>

为了清晰起见,我喜欢这样......如果您发现列表理解清晰的话。它确实创建了两个临时列表:pp[1:] 和 zip() 结果。然后它会比较所有相邻对并给出它发现的第一个更改。

这个看起来类似的生成器表达式不会创建临时列表,并在到达第一个更改时停止处理:

>>> from itertools import islice, izip
>>> ([t1, t2] for ((t1, v1), (t2, v2)) in izip(pp, islice(pp, 1, None)) 
...           if v1 != v2
... ).next()
['c', 'd']
>>>

此页面上的每个人的示例都比您想要捕获错误时的示例更紧凑。

>>> pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
>>> [[t1, t2] for ((t1, v1), (t2, v2)) in zip(pp, pp[1:]) if v1 != v2] [0]
['c', 'd']
>>>

I like this for clarity...if you find list comprehensions clear. It does create two temporary lists: pp[1:] and the zip() result. Then it compares all the adjacent pairs and gives you the first change it found.

This similar-looking generator expression doesn't create temporary lists and stops processing when it reaches the first change:

>>> from itertools import islice, izip
>>> ([t1, t2] for ((t1, v1), (t2, v2)) in izip(pp, islice(pp, 1, None)) 
...           if v1 != v2
... ).next()
['c', 'd']
>>>

Everybody's examples on this page are more compact than they would be if you wanted to catch errors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文