Python:确定列表列表是否包含已定义的序列

时间:2014-08-23 03:10:21

标签: python algorithm function loops

我有一个子列表列表,我想看看第一个子列表中的任何整数值加一个是否包含在第二个子列表中。对于所有这些值,我想看看该值加1是否包含在第三个子列表中,依此类推,以这种方式在所有子列表中进行。如果有一种方式从第一个子列表到最后一个子列表以这种方式进行,我希望返回True;否则我希望返回False。对于第一个子列表中的每个值,我想看看是否可以在从左到右阅读的每个子列表中找到该值加n,其中n是较大列表中该子列表的索引值。(对于笨拙的措辞 - 抱歉 - - 我不确定如何在不使用更多单词的情况下清理语言。)

编辑:(之前关于所需输出的清晰度是不明确的。)对于第一个子列表中的每个值,我想看看是否可以从左到右读取每个子列表中的值加n,其中n是索引值该子列表在较大的列表中。

这是我写的。

a = [ [1,3],[2,4],[3,5],[6],[7] ]

def find_list_traversing_walk(l):

    for i in l[0]:

        index_position = 0
        first_pass = 1
        walking_current_path = 1

        while walking_current_path == 1:

            if first_pass == 1:
                first_pass = 0
                walking_value = i

            if walking_value+1 in l[index_position + 1]:

                index_position += 1
                walking_value  += 1

                if index_position+1 == len(l):
                    print "There is a walk across the sublists for initial value ", walking_value - index_position
                    return True

            else:
                walking_current_path = 0

    return False

print find_list_traversing_walk(a)

我的问题是:我是否在这里忽略了一些简单的事情,或者这个函数对于所有真正的正面都会返回True而对于所有真正的负面都会返回False吗?有没有更简单的方法来完成预期的任务?我将非常感谢其他人提供的任何反馈!

3 个答案:

答案 0 :(得分:2)

  

是否有更简单的方法来完成预期的任务?

是的,定义递归解决方案会更容易:

def find(lst, index):
    if index == len(lst)-1:
        return True
    for i in lst[index]:
        if i+1 in lst[index+1]:
            return find(lst, index+1)
    else:
        return False             

a = [ [1,3],[2,4],[3,5],[6],[7] ]
print find(a, 0) # prints "True"

a = [ [1,3],[2,4],[3,5],[6],[7], [9] ]
print find(a, 0) # prints "False"

<强>更新
你在评论中描述的内容有点复杂(next+1需要成为之前使用过的人之一) - 但并不多:

def find(lst, part_res, index):
    if index == len(lst)-1:
        return True

    found = False
    new_part_res = []
    for i in part_res:
        if i+1 in lst[index+1]:
            found = True
            new_part_res.append(i+1)

    if not found:
        return False
    else:
        return find(lst, new_part_res, index+1)


a = [ [1,3],[2,4],[3,5],[6],[7] ] 
print find(a, a[0], 0) # True

a = [ [1],[2,4],[5] ]
print find(a, a[0], 0) # False

答案 1 :(得分:2)

您可以在一系列集合中以减少的形式查看所需的操作,其中减少操作是以下功能:

In [25]: def func(x, y):
   ....:     return set([t+1 for t in x]) & set(y)
   ....:

也就是说,func接受两个集合,为第一个集合中的每个元素添加1,并返回该集合和第二个集合的交集。在a之间按顺序应用此功能。如果最终结果不是空集,则答案为True:

In [29]: a = [ [1,3],[2,4],[3,5],[6],[7] ]

In [30]: bool(reduce(func, a))
Out[30]: True

In [31]: b = [ [1],[2,4],[5] ]

In [32]: bool(reduce(func, b))
Out[32]: False

bool将非空集转换为True,将空集转换为False。)

请注意,如果输入通常是一个非常长的序列,并且您希望在几个步骤中知道答案为False,那么这不是一个非常有效的解决方案,因为它总是遍历整个输入。

答案 2 :(得分:0)

我还认为它是递归表达得更好。如果我理解你的问题,这就是我想出来的。

a = [ [1,3],[2,4],[3,5],[6],[7] ]
b = [ [1],[2,4],[5] ]
c = [ [1,3],[2,4],[3,5],[6, 4],[5, 7] ]

def foo(data):
    if len(data) == 1:
        return True
    return all(item + 1 in data[1] for item in data[0]) and foo(data[1:])

print foo(a), foo(b), foo(c)
>>> 
False False True
>>>