确定字符是否在第一次出现另一个字符之前出现

时间:2017-07-08 02:10:19

标签: python

我希望能够输入一个字母列表(列表中的字母只有四个选项),但是列表最多可以包含十个项目,例如:

letter_options = ['A', 'B', 'C', 'D']

s = ['B', 'C', 'A', 'C', 'D', 'A']
s = ['C', 'A', 'D', 'C', 'A']
s = ['A', 'B', 'A', 'A', 'D', 'B', 'B']

我的问题是如何在'D'或'A'出现之前确定'B'是否发生?如果列表中不存在“B”,则代码将输出0.如果“B”确实发生在“A”或“D”之前,则代码将输出1.

这是我所拥有的,但它不适用于没有发生'B'的情况。

letters = ['A', 'A', 'A', 'A']
fkt = []

check = ' '.join(letters).split('B')[0].split()
if letters!=[] and letters[0]=='B':
    fkt.append(1)
elif letters!=[] and any(idx in check for idx in ['A', 'D']):
    fkt.append(0)
else:
    fkt.append(1)

2 个答案:

答案 0 :(得分:2)

如果['B', 'C', 'A', 'C', 'D', 'A']是您的列表,并且您想知道“B”是否在“D”之前,您可以将列表转换为字符串,然后使用str.find

In [141]: l = ''.join(['B', 'C', 'A', 'C', 'D', 'A'])

In [148]: l[:max(0, l.find('D'))].find('A') > -1
Out[148]: True

一般来说,

In [153]: def foo(l, c1, c2): # is c2 before c1?
     ...:     return l[:max(0, l.find(c1))].find(c2) > -1
     ...: 

In [154]: foo(l, 'B', 'D')
Out[154]: False

In [155]: foo(l, 'D', 'B')
Out[155]: True   

str.find返回-1,因此您可以优雅地处理无匹配,因为拼接到0[:0])会返回一个空列表。

VPfB建议的更简单的替代方案是0 <= l.find('X') < l.find('Y')

def foo(l, c1, c2): # is c2 before c1?
    return `0 <= l.find('c2') < l.find('c1')`

答案 1 :(得分:1)

你可以尝试这种方法:

def code(lst):
    for i in lst:
        # loop through the list, if find the element A or D, return 0 and break out of 
        # the loop
        if i in ['A', 'D']:
            return 0
        # if find B, return 1 and break out of the loop
        elif i == 'B':
            return 1
    # if not find B at all return 0 and break out of the loop
    return 0

s1 = ['B', 'C', 'A', 'C', 'D', 'A']
s2 = ['C', 'A', 'D', 'C', 'A']
s3 = ['A', 'B', 'A', 'A', 'D', 'B', 'B']

code(s1)
#1

code(s2)
#0

code(s3)
#0

或等效地:

bfirst = 0
for i in lst:
    if i in ['A', 'D']:
        bfirst = 0
        break
    elif i == 'B':
        bfirst = 1
        break

理由

使用简单的for循环,如果要检查值,如果首先找到'AD',则bfirst为0并且短路(断开循环),因为不再需要检查其他元素;类似地,如果首先找到'B',则出于同样的原因分配bfirst 1和短路(断开循环);如果你有一个很长的列表和很少的字母选项,这可能非常有效,因为它只检查列表开头的几个字母而不必彻底遍历列表;在最糟糕的情况下(列表完全由不相关的字母组成),它仍然是O(N),列表的一次通过。