确定 python 0 和 1 列表中序列类型的最有效方法?

Most efficient way to determine the type of sequence in a python list of 0s and 1s?

假设我们有 python 个随机大小的列表,其值以 0 和 1 的随机序列排列。确定序列是否为以下类型之一(最多 3 个位置)以及 return 以下“序列类型”字符串之一的好方法是什么?:

我能想到简单的情况,然后是嵌套循环并保留计数器的天真方法,但是有没有更优雅的方法来做到这一点?

def sequence_type(sequence):
    
if 0 not in sequence:
    return '1'

elif 1 not in sequence:
    return '0'

else:
    if sequence[0] == 0:
        # loop through for sequence type 0xx
    elif sequence[0] == 1:
        # loop through for sequence type 1xx

编辑:我们不关心在检查类型时序列末尾的内容,而是在查看前 3 个“唯一”数字时序列是什么。

例如:[0,0,1,0,1,0] 是类型 010,因为:

您可以 return 通过逐个位来确定序列类型。类型的第一位数字始终等于第一位。如果在第一个位置之后找到反转位,则该类型将有两个或三个数字,第二个数字是第一个数字的倒数。如果该位出现在反转位置之后,则序列类型为 3 位(再次交替):

def seqType(seq):
    bit = seq[0]                 # seq type starts with first bit
    try: p = seq.index(1-bit)    # search position of inverse bit
    except: return str(bit)      # not found --> single digit type
    if bit not in seq[p+1:]:     # search for initial bit after inverse
        return f"{bit}{1-bit}"   # not found --> two digit type
    return f"{bit}{1-bit}{bit}"  # --> 3 digit type

    

输出:

tests = ([0,0,0],[1,1],[0,0,0,0,1],[1,0,0,0,0],
         [0,0,0,1,0,1,1,0],[1,1,1,1,1,0,0,1,0,1,0,1])    
for seq in tests:
    print(seq,seqType(seq))
    
[0, 0, 0] 0
[1, 1] 1
[0, 0, 0, 0, 1] 01
[1, 0, 0, 0, 0] 10
[0, 0, 0, 1, 0, 1, 1, 0] 010
[1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1] 101 

如果您想要更高级的方法,可以使用 zip 函数计算类型以压缩相同的连续位。压缩序列的前 3 位将对应序列类型:

def seqType(seq):
    return "".join(str(a) for a,b in zip(seq,seq[1:]+[2]) if a!=b)[:3])

或者,如果您喜欢递归解决方案:

def seqType(seq):
    if len(seq) == 1:  return str(seq[0])
    if seq[0]==seq[1]: return seqType(seq[1:])
    return str(seq[0]) + seqType(seq[1:])[:2]

如果我对你的理解正确,你正在解析 regular language, so you can implement it as a finite-state automaton

这是 C 中的示例:

bool start(char *s) {
  if (*s) {
    if (*s++ == '0') A(s);
    else B(s);
  } else /* empty string doesn't match anything (or it's both a type "0" and type "1" */ 
}

bool A(char *s) {
  if (*s) {
    if (*s++ == '0') A(s);
    else C(s);
  } else /* "0" */
}

bool B(char *s) {
  if (*s) {
    if (*s++ == '0') D(s);
    else E(s)
  } else /* "1" */
}

bool C(char *s) {
  if (*s) {
    if (*s++ == '0') /* "010" */
    else /* Should be illegal. */
  } else /* "01" */
}

bool D(char *s) {
  if (*s) {
    if (*s++ == '0') G(s);
    else /* "101" */
  } else /* "10" */

bool E(char *s) {
  if (*s) {
    if (*s++ == '0') F(s);
    else E(s);
  } else /* "1" */
}

bool F(char *s) {
  if (*s) {
    if (*s++ == '0') /* illegal */
    else /* "101" */
  } else 
}

bool G(char *s) {
  if (*s) {
    if (*s++ == '0') G(s);
    else /* "101" */
  } else /* "10" */
}

这可能不是对有限状态自动机进行编码的最简洁的方式,但按照这些思路应该可行——有限自动机当然是优雅的结构。

你也可以正则表达式。