mmacheerpuppy - 4 months ago 10
Python Question

# Matching up iterables in lists, having significant difficulty

For a personal project I have three lists. One of these contains a set of arrays (l2) the size of which is always determined by a setting l2_size and always contains random members of l1. The next array, l3, on the other hand will always be a set of 0's of quantity len(l1).

This means...

``````l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
``````

I need to perform a search such that

1. Beginning with l2[0] if the pointer l2[0] hits l2[0], search through l1 to find l1[i] == the first value of l2[0].

2. Once the first value of l2[0] use l3 to assign its corresponding value.

3. Since the size of the arrays in l2[0] are 5 members we are going to assign a corresponding value of 1 to l3 a maximum of five times. Once we have hit that target we're moving onto the next set l2[1].

4. Once we are done with l2[0] (so on to l2[1]) we need to assign the next corresponding value, so 2, without over-writing the values in l3.

Illustration...

Imagine these are baseball scoring cards... I have l1 baseball cards in my deck. The compositions of baseball scoring cards I want in my hands are contained in l2. These cards will win me the game! In this case l2 = [1,2,3,4,5]. I'm a massive cheater and must find all l2 in l1 (cards for hands). Finding l2 in l1 I mark where they are using l3. I also use l3 to tell me which hand to put them in.

To be a valid solution we must uniquely pair up the values in l2 such that they are uniquely identified as values in l1 using l3. This would mean...

``````l1 = [1,2,3,4,5,1,2,3,4,5]
l2 = [[1,2,3,4,5],[1,2,3,4,5]]
l3 = [1,1,1,1,1,2,2,2,2,2]
``````

Would be valid. But...

``````l1 = [1,2,3,4,5,1,2,3,4,5]
l2 = [[1,2,3,4,5],[1,2,3,4,5]]
l3 = [1,2,1,1,1,2,2,1,2,2]
``````

Would be invalid because there is no hand in l2 containing [2,1,2,4,5] in any order.

Example

From l2[0] we are going to iterate through l1 over and over and pick up all the objects in l2[0] and sign them off to l3. This should then look like (by hand)...

``````l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [0,0,1,1,1,0,1,0,1,0,0,0,0,0,0]
``````

The value 1 has been assigned in l3 since these are the first instances of the corresponding values we come across. We are done with l2[0] now because we have found all of its items in l1. The next job is l2[1]...

``````l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [2,2,1,1,1,0,1,0,1,0,0,0,2,2,2]
``````

This is what I've cooked up but to no avail...

``````assignvar = 1
pos = 0
for x in l2:
for y in x:
for z in l1:
while userpos < len(l1):
if y == z:
l1[pos] = assignvar
while l2_size == pos:
assignvar += 1
l2_size = l2_size+l2_size #stops pos going out of range, changes assignvar to 2 (so appending the next set of l3 iterables to 2 .etc)
userpos = userpos+1
``````

Really quite confounded how to approach this issue in my code. I feel like I have the right idea using the three for loops but I've been hitting this with my wrench for a while now and completely burned out.

get sublist first, then using sublist's element get l1's index. increase 1 for l3 element based on l1's index

``````l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

def combinList( lst ):
''' put list of list together based on index
for example:
a = [1,3,5,7]
b = [2,4,6,8]
combined list should be [1,2,3,4,5,6,7,8] '''
step = len(lst)
res= [None]*len(  reduce(lambda x,y:x+y, lst))
for i,item in enumerate(lst):
res[i::step] = sorted(item)
return res

for value,line in enumerate(l2):
counter = 0
record = {}
# count how many time this element appeared
for i in line:
record[ i -1 ] = record.get( i - 1,0) + 1
newList = combinList( [ [ i for i,j in enumerate(l1) if item == j] for item in line ] )
for idx in newList:
# if this element of l3 hasn't been change and there is at least one associated element in l2,put the value to l3 and reduce the number of l2
if not l3[idx] and record.get(idx%5,0):
l3[idx] = value + 1
counter+=1
record[idx%5] = record[idx%5] -1
if counter >=5:
break
print l3
print l3
``````

output:

``````#first iteration
[0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
#second iteration
[2, 1, 1, 1, 1, 0, 2, 2, 1, 2, 0, 0, 0, 2, 0]
#third iteration
[2, 1, 1, 1, 1, 3, 2, 2, 1, 2, 0, 3, 3, 2, 3]
#final iteration
[2, 1, 1, 1, 1, 3, 2, 2, 1, 2, 0, 3, 3, 2, 3]
``````