Reputation: 27584
I have a list of sublists, and I want to see if any of the integer values from the first sublist plus one are contained in the second sublist. For all such values, I want to see if that value plus one is contained in the third sublist, and so on, proceeding in this fashion across all sublists. If there is a way of proceeding in this fashion from the first sublist to the last sublist, I wish to return True; otherwise I wish to return False. For each value in the first sublist, I want to see if one can find that value plus n in each sublist reading left to right, where n is the index value of that sublist within the larger list.. (Sorry for the clumsy phrasing--I'm not sure how to clean up my language without using many more words.)
EDIT: (The previous articulation of desired output is ambiguous.) For each value in the first sublist, I want to see if one can find that value plus n in each sublist reading left to right, where n is the index value of that sublist within the larger list.
Here's what I wrote.
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)
My question is: Have I overlooked something simple here, or will this function return True for all true positives and False for all true negatives? Are there easier ways to accomplish the intended task? I would be grateful for any feedback others can offer!
Upvotes: 0
Views: 214
Reputation: 114781
You can view the desired operation as a reduction on a sequence of sets where the reducing operation is the following function:
In [25]: def func(x, y):
....: return set([t+1 for t in x]) & set(y)
....:
That is, func
takes two collections, adds 1 to each element in the first collection, and returns the intersection of that and the second collection. Apply this function sequentially across a
. If the final result is not an empty set, the answer is 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
converts a non-empty set to True and an empty set to False.)
Note that if the input is typically a very long sequence, and you expect to know that the answer is False within a few steps, this is not a very efficient solution, since it always traverses the entire input.
Upvotes: 2
Reputation: 23743
I also thought it was expressed better recursively. If I understood your problem correctly, this is what I came up with.
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
>>>
Upvotes: 0
Reputation: 53525
Are there easier ways to accomplish the intended task?
Yes, it will be easier to define a recursive solution:
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"
UPDATE
What you describe in your comment is a bit more complex (the need for the next+1
to be one of the "guys" that were used before) - but not much:
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
Upvotes: 2