必须有一种更简单,更pythonic的方式来做到这一点。
鉴于这对配对列表:
pp = [('a',1),('b',1),('c',1),('d',2),('e',2)]
如何最容易找到第二个项目更改的相邻对中的第一个项目(此处为1到2)。因此,我正在寻找['c','d']。假设整个列表中对[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
由于 添
答案 0 :(得分:2)
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)
添加了我的可读生成器版本。
答案 1 :(得分:0)
您可以尝试以下方式:
[[pp[i][0],pp[i+1][0]] for i in xrange(len(pp)-1) if pp[i][1]!=pp[i+1][1]][0]
(使用列表理解)
答案 2 :(得分:0)
尝试将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()
答案 3 :(得分:0)
>>> 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')
答案 4 :(得分:0)
以下是递归的简单?(
)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))
答案 5 :(得分:0)
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)
答案 6 :(得分:0)
>>> 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']
>>>
如果你想捕捉错误,那么这个页面上的每个人的例子都比你想要的更紧凑。