Check if the two items in the list are in a specific order?

Say I have a list v = [1, 2, 3, 4, 3, 1, 2]. I want to write a function find_pairthat will check if two numbers are in the list and next to each other. So, find_pair(v, 2, 3)must return True, but find_pair(v, 1, 4)must return False.

Is it possible to implement find_pairwithout a loop?

+6
source share
13 answers
v = [1,2,3,4,3,1,2]
any([2,3] == v[i:i+2] for i in xrange(len(v) - 1))

While the @PaoloCapriotti version does this trick, it is faster because it stops analyzing vas soon as a match is found.

+10
source
[2, 3] in [v[i:i+2] for i in range(len(v) - 1)]
+3
source

, , , ( v ):

' 2, 3' in str(v)
+3
v = [1,2,3,4,3,1,2]

def find(x,y,v):
        return (x,y) in zip(v,v[1:])

print find(2,3,v)
print find(1,4,v)
+2

, :

a = range(100)
exists = (55,56) in zip(a, a[1:])
+2

. , [.., 2, 3].

. ? , , , , , . , . , . .

+1

.

Python, in, Python .

+1

Boyer-Moore . , , .

def find_pair(seq, a, b):
    i = 1
    while i < len(seq):
        if seq[i] == b and seq[i - 1] == a: return i - 1
        i += 2 - (seq[i] == a)

print find_pair([1, 5, 3, 4, 3, 1, 2, 3, 3], 2, 3)
+1

, , , . [1] node [2], [2] [3] [3] a [4]. . 2 .

node, , append-only. , , subsequnce, . O (2 * k), k - . , 20 , , .

2, , . . O ( * k) . , hashtables.

0

, ,

>>> v = [1,2,3,4,3,1,2]
def InList(v,(i,j)):
    start=1
    try:
         while True:
            if v[v.index(i,start)+1]==j and v[v.index(j,start)-1]==i:
                return True
            start=v.index(i)+1
    except IndexError:
        return False
    except ValueError:
        return False


>>> InList(v,(2,3))
True
>>> InList(v,(4,5))
False
>>> InList(v,(1,2))
True
>>> InList(v,(12,2))
False
>>> InList(v,(3,1))
True

Ok , ,

>>> stmt1="""
v = [1,2,3,4,3,1,2]
def InList(v,(i,j)):
    start=1
    try:
         while True:
            if v[v.index(i,start)+1]==j and v[v.index(j,start)-1]==i:
                return True
            start=v.index(i)+1
    except IndexError:
        return False
    except ValueError:
        return False
InList(v,(2,3))
InList(v,(4,5))
InList(v,(1,2))
InList(v,(12,2))
"""
>>> stmt2="""
v = [1,2,3,4,3,1,2]
def InList(v,(x,y)):
    any([x,y] == v[i:i+2] for i in xrange(len(v) - 1))
InList(v,(2,3))
InList(v,(4,5))
InList(v,(1,2))
InList(v,(12,2))
"""
>>> t1=timeit.Timer(stmt=stmt1)
>>> t2=timeit.Timer(stmt=stmt2)
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000)
13.67 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000)
20.67 usec/pass
>>> 

, .

** , . , .

0

eumiro , - , list.index(), .

v = [1,2,3,4,3,1,2]

def f1(items):
    return any([2,3] == v[i:i+2] for i in xrange(len(v) - 1))

def f2(items):
    i = 0
    index = items.index
    try:
        while 1:
            i = index(2, i) + 1
            if items[i] == 3:
                return True
    except IndexError:
        return False

from timeit import repeat    
print "f1", min(repeat("f1(v)", "from __main__ import f1, v", number=1000))
print "f2", min(repeat("f2(v)", "from __main__ import f2, v", number=1000))

, :

f1 0.00300002098083
f2 0.0

, .

0

, True False , , , :

def find_pair(list, x, y):
    if abs(list.index(x)-list.index(y)) == 1:
        print(True)
    else:
        print(False)

But if the order of the elements is important, then remove the abs () function inside the if condition. UPDATE:

More reliable may be (if u is expected to follow x):

def find_pair(list, x, y):
if list[list.index(x)+1] == y:
    print(True)
else:
    print(False)
0
source

Combining several ideas here, they both seem to be doing their job very quickly.

def InList(v, (x, y)):
    return any((x == v[i] and y == v[i + 1]) for i in xrange(len(v) - 1))

def FasterInList(v, (x, y)):
    if x in v:
        indices = [i for i, match in enumerate(v) if match == x]
        for i in indices:
            if v[i+1] == y:
                return True
    return False

The simpler version of InList is only slightly slower than the @abhijit solution, but it performs one test less, but still almost twice as fast as the top solution. The FasterInList version is about 25% faster than InList.

import timeit

abhijit = """
v = [1,2,3,4,3,1,2]
def abhijit(v,(i,j)):
    start=1
    try:
         while True:
            if v[v.index(i,start)+1]==j and v[v.index(j,start)-1]==i:
                return True
            start=v.index(i)+1
    except IndexError:
        return False
    except ValueError:
        return False
abhijit(v,(2,3))
abhijit(v,(4,5))
abhijit(v,(1,2))
abhijit(v,(12,2))
"""
# abhijit(v,(3,2)) this never breaks out of the while loop

top = """
v = [1,2,3,4,3,1,2]
def top(v,(x,y)):
    any([x,y] == v[i:i+2] for i in xrange(len(v) - 1))
top(v,(2,3))
top(v,(4,5))
top(v,(1,2))
top(v,(12,2))
top(v,(3,2))
"""

InList = """
v = [1,2,3,4,3,1,2]
def InList(v, (x, y)):
    return any((x == v[i] and y == v[i + 1]) for i in xrange(len(v) - 1))
InList(v,(2,3))
InList(v,(4,5))
InList(v,(1,2))
InList(v,(12,2))
InList(v,(3,2))
"""

FasterInList = """
v = [1,2,3,4,3,1,2]
def FasterInList(v, (x, y)):
    if x in v:
        indices = [i for i, match in enumerate(v) if match == x]
        for i in indices:
            if v[i + 1] == y:
                return True
    return False
FasterInList(v,(2,3))
FasterInList(v,(4,5))
FasterInList(v,(1,2))
FasterInList(v,(12,2))
FasterInList(v,(3,2))
"""
top_timer = timeit.Timer(stmt=top)
abhijit_timer = timeit.Timer(stmt=abhijit)
InList_timer = timeit.Timer(stmt=InList)
FasterInList_timer = timeit.Timer(stmt=FasterInList)

print "%.2f usec/pass" % (1000000 * top_timer.timeit(number=100000)/100000)  # 8.79 usec/pass
print "%.2f usec/pass" % (1000000 * abhijit_timer.timeit(number=100000)/100000)  # 4.42 usec/pass
print "%.2f usec/pass" % (1000000 * InList_timer.timeit(number=100000)/100000)  # 4.66 usec/pass
print "%.2f usec/pass" % (1000000 * FasterInList_timer.timeit(number=100000)/100000)  # 3.70 usec/pass
0
source

All Articles