Split list recursively until flat - python

I'm writing a passion program that will determine the best poker hand given hole cards and community cards. As an ace can go both ways in a straight, I've coded this as [1, 14] for a given 5 card combination.
I understand recursion but implementing it is a different story for me. I'm looking for a function that will split all aces recursively, into all possible hand combinations until all nested lists are exhausted. This should obviously work with up to 4 aces, overlooking the fact that you wouldn't care about a straight at that point in all likelihood.
hand = [[1, 14], 2, 3, [1, 14], 7]
desired_output = [
[1, 2, 3, 1, 7],
[1, 2, 3, 14, 7],
[14, 2, 3, 1, 7],
[14, 2, 3, 14, 7]
]
I'm not proud of what I have so far, especially because it returns a list instead of something like a yield which would build the list I'm looking for:
def split_first_ace(hand):
aces = [True if isinstance(x, list) else False for x in hand]
for i, x in enumerate(aces):
if x:
ranks_temp = hand.copy()
ace = ranks_temp.pop(i)
return [[ace[0]] + ranks_temp, [ace[1]] + ranks_temp]
Any help on a solution would be appreciated, mostly because it'll help me understand how to implement recursion. But I'm open to other solutions as well.

Well, there is an easier way to do this:
from itertools import product
product(*[i if isinstance(i, list) else [i] for i in hand])
I challenge everybody to come up with a simpler solution

The itertools.product() function might be useful. If we assume that the recursion will only be 1 level deep (aces don't have nested lists themselves), then we could use the following:
from itertools import product
hand = [[1, 14], 2, 3, [1, 14], 7]
aces = [x for x in hand if isinstance(x, list)]
rest = [x for x in hand if isinstance(x, int)]
combinations = [list(x) + rest for x in product(*aces)]
print(combinations)
Yields:
[[1, 1, 2, 3, 7], [1, 14, 2, 3, 7], [14, 1, 2, 3, 7], [14, 14, 2, 3, 7]]

This might be overkill since you only need one level of recursion (like #Aaron Keesing's answer) but this should work:
def iter_hands(hand, __current_index=0, __current_combo=None):
__current_combo = __current_combo or []
if __current_index == len(hand):
yield __current_combo.copy()
return
choices = hand[__current_index]
if not isinstance(choices, list):
choices = [choices]
for c in choices:
__current_combo.append(c)
yield from iter_hands(hand, __current_index + 1, __current_combo)
__current_combo.pop()
def main():
input_hand = [[1, 14], 2, 3, [1, 14], 7]
want_hands = [
[1, 2, 3, 1, 7],
[1, 2, 3, 14, 7],
[14, 2, 3, 1, 7],
[14, 2, 3, 14, 7]
]
got_hands = [hand for hand in iter_hands(input_hand)]
assert want_hands == got_hands
if __name__ == '__main__':
main()

Related

How to make ascending sublists in a list of integers go in descending order?

Working on some example questions, the particular one asks to make a function which would take a list and return a new one which would make every ascending sublist in the list go in descending order and leave the descending sublists as they are. For example, given the list [1,2,3,4,5], I need the list [5,4,3,2,1] or given a list like [1,2,3,5,4,6,7,9,8] would return [5,3,2,1,9,7,6,4,8]
Here's what I have so far, but it does not do anything close to what I'd like it to do:
def example3(items):
sublst = list()
for i in items:
current_element = [i]
next_element = [i+1]
if next_element > current_element:
sublst = items.reverse()
else:
return items
return sublst
print (example3([1,2,3,2])) #[[1, 2, 3, 2], [1, 2, 3, 2], [1, 2, 3, 2], [1, 2, 3, 2]]
EDIT:
I feel like people are a little confused as to what I want to do in this case, heres a better example of what I'd like my function to do. Given a list like: [5, 7, 10, 4, 2, 7, 8, 1, 3] I would like it to return [10, 7, 5, 4, 8, 7, 2, 3, 1]. As you can see all the sublists that are in descending order such as ([5,7,10]) gets reversed to [10, 7, 5].
It was a bit challenging to figure out what you need.
I think you want something like as follows:
import random
l = [5, 7, 10, 4, 2, 7, 8, 1, 3]
bl =[]
while True:
if len(l) == 0:
break
r = random.randint(0, len(l))
bl.extend(l[r:None:-1])
l = l[r+1:]
print(bl)
Out1:
[10, 7, 5, 4, 8, 7, 2, 3, 1]
Out2:
[10, 7, 5, 2, 4, 1, 8, 7, 3]
Out3:
[3, 1, 8, 7, 2, 4, 10, 7, 5]
Out4:
[2, 4, 10, 7, 5, 3, 1, 8, 7]
etc.
If you want a specific reverse random list:
import random
loop_number = 0
while True:
l = [5, 7, 10, 4, 2, 7, 8, 1, 3]
bl =[]
while True:
if len(l) == 0:
break
r = random.randint(0, len(l))
bl.extend(l[r:None:-1])
l = l[r+1:]
loop_number += 1
if bl == [10, 7, 5, 4, 8, 7, 2, 3, 1]:
print(bl)
print("I tried {} times".format(loop_number))
break
Out:
[10, 7, 5, 4, 8, 7, 2, 3, 1]
I tried 336 times
The general algorithm is to keep track of the current ascending sublist you are processing using 2 pointers, perhaps a "start" and "curr" pointer. curr iterates over each element of the list. As long as the current element is greater than the previous element, you have an ascending sublist, and you move curr to the next number. If the curr number is less than the previous number, you know your ascending sublist has ended, so you collect all numbers from start to curr - 1 (because array[curr] is less than array[curr - 1] so it can't be part of the ascending sublist) and reverse them. You then set start = curr before incrementing curr.
You will have to deal with the details of the most efficient way of reversing them, as well as the edge cases with the pointers like what should the initial value of start be, as well as how to deal with the case that the current ascending sublist extends past the end of the array. But the above paragraph should be sufficient in getting you to think in the right direction.

Python: Find-replace on lists

I first want to note that my question is different from what's in this link:
finding and replacing elements in a list (python)
What I want to ask is whether there is some known API or conventional way to achieve such a functionality (If it's not clear, a function/method like my imaginary list_replace() is what I'm looking for):
>>> list = [1, 2, 3]
>>> list_replace(list, 3, [3, 4, 5])
>>> list
[1, 2, 3, 4, 5]
An API with limitation of number of replacements will be better:
>>> list = [1, 2, 3, 3, 3]
>>> list_replace(list, 3, [8, 8], 2)
>>> list
[1, 2, 8, 8, 8, 8, 3]
And another optional improvement is that the input to replace will be a list itself, instead of a single value:
>>> list = [1, 2, 3, 3, 3]
>>> list_replace(list, [2, 3], [8, 8], 2)
>>> list
[1, 8, 8, 3, 3]
Is there any API that looks at least similar and performs these operations, or should I write it myself?
Try;
def list_replace(ls, val, l_insert, num = 1):
l_insert_len = len(l_insert)
indx = 0
for i in range(num):
indx = ls.index(val, indx) #it throw value error if it cannot find an index
ls = ls[:indx] + l_insert + ls[(indx + 1):]
indx += l_insert_len
return ls
This function works for both first and second case;
It wont work with your third requirement
Demo
>>> list = [1, 2, 3]
>>> list_replace(list, 3, [3, 4, 5])
[1, 2, 3, 4, 5]
>>> list = [1, 2, 3, 3, 3]
>>> list_replace(list, 3, [8, 8], 2)
[1, 2, 8, 8, 8, 8, 3]
Note
It returns a new list; The list passed in will not change.
how about this, it work for the 3 requirements
def list_replace(origen,elem,new,cantidad=None):
n=0
resul=list()
len_elem=0
if isinstance(elem,list):
len_elem=len(elem)
for i,x in enumerate(origen):
if x==elem or elem==origen[i:i+len_elem]:
if cantidad and n<cantidad:
resul.extend(new)
n+=1
continue
elif not cantidad:
resul.extend(new)
continue
resul.append(x)
return resul
>>>list_replace([1,2,3,4,5,3,5,33,23,3],3,[42,42])
[1, 2, 42, 42, 4, 5, 42, 42, 5, 33, 23, 42, 42]
>>>list_replace([1,2,3,4,5,3,5,33,23,3],3,[42,42],2)
[1, 2, 42, 42, 4, 5, 42, 42, 5, 33, 23, 3]
>>>list_replace([1,2,3,4,5,3,5,33,23,3],[33,23],[42,42,42],2)
[1, 2, 3, 4, 5, 3, 5, 42, 42, 42, 23, 3]
Given this isn't hard to write, and not a very common use case, I don't think it will be in the standard library. What would it be named, replace_and_flatten? It's quite hard to explain what that does, and justify the inclusion.
Explicit is also better than implicit, so...
def replace_and_flatten(lst, searched_item, new_list):
def _replace():
for item in lst:
if item == searched_item:
yield from new_list # element matches, yield all the elements of the new list instead
else:
yield item # element doesn't match, yield it as is
return list(_replace()) # convert the iterable back to a list
I developed my own function, you are welcome to use and to review it.
Note that in contradiction to the examples in the question - my function creates and returns a new list. It does not modify the provided list.
Working examples:
list = [1, 2, 3]
l2 = list_replace(list, [3], [3, 4, 5])
print('Changed: {0}'.format(l2))
print('Original: {0}'.format(list))
list = [1, 2, 3, 3, 3]
l2 = list_replace(list, [3], [8, 8], 2)
print('Changed: {0}'.format(l2))
print('Original: {0}'.format(list))
list = [1, 2, 3, 3, 3]
l2 = list_replace(list, [2, 3], [8, 8], 2)
print('Changed: {0}'.format(l2))
print('Original: {0}'.format(list))
I always print also the original list, so you can see that it is not modified:
Changed: [1, 2, 3, 4, 5]
Original: [1, 2, 3]
Changed: [1, 2, 8, 8, 8, 8, 3]
Original: [1, 2, 3, 3, 3]
Changed: [1, 8, 8, 3, 3]
Original: [1, 2, 3, 3, 3]
Now, the code (tested with Python 2.7 and with Python 3.4):
def list_replace(lst, source_sequence, target_sequence, limit=0):
if limit < 0:
raise Exception('A negative replacement limit is not supported')
source_sequence_len = len(source_sequence)
target_sequence_len = len(target_sequence)
original_list_len = len(lst)
if source_sequence_len > original_list_len:
return list(lst)
new_list = []
i = 0
replace_counter = 0
while i < original_list_len:
suffix_is_long_enough = source_sequence_len <= (original_list_len - i)
limit_is_satisfied = (limit == 0 or replace_counter < limit)
if suffix_is_long_enough and limit_is_satisfied:
if lst[i:i + source_sequence_len] == source_sequence:
new_list.extend(target_sequence)
i += source_sequence_len
replace_counter += 1
continue
new_list.append(lst[i])
i += 1
return new_list
I developed a function for you (it works for your 3 requirements):
def list_replace(lst,elem,repl,n=0):
ii=0
if type(repl) is not list:
repl = [repl]
if type(elem) is not list:
elem = [elem]
if type(elem) is list:
length = len(elem)
else:
length = 1
for i in range(len(lst)-(length-1)):
if ii>=n and n!=0:
break
e = lst[i:i+length]
if e==elem:
lst[i:i+length] = repl
if n!=0:
ii+=1
return lst
I've tried with your examples and it works ok.
Tests made:
print list_replace([1,2,3], 3, [3, 4, 5])
print list_replace([1, 2, 3, 3, 3], 3, [8, 8], 2)
print list_replace([1, 2, 3, 3, 3], [2, 3], [8, 8], 2)
NOTE: never use list as a variable. I need that object to do the is list trick.

how to merge two sublists sharing any number in common?(2)

Given that:
list=[[1,2,3],[3,4,5],[5,6],[6,7],[9,10],[10,11]]
I have asked a similar question before, I have tried the code on
how to merge two sublists sharing any number in common?
but I am stuck in my code now.
I want to merge the sublists that share a common number,
e.g. [1,2,3] and [3,4,5] can merge to give [1,2,3,4,5] as they share a common number, 3.
In [[1,2,3],[3,4,5],[5,6]], although [1,2,3] and [3,4,5] share a common number, 3,
[3,4,5] and [5,6] also share a common number, 5, so I want all three of them to merge then gives
[1,2,3,4,5,6].
So for list,
my expected result is:
[[1,2,3,4,5,6,7],[9,10,11]]
I have tried the following code but don't know what is wrong, can anyone help?
s = map(set, list)
for i, si in enumerate(s):
for j, sj in enumerate(s):
if i != j and si & sj:
s[i] = si | sj
s[j] = set()
list=[list(el) for el in s if el]
print list
>>>[[5, 6, 7], [9, 10, 11]]
def merge_containing(input_list):
merged_list = [set(input_list[0])]
i = 0
for sub_list in input_list:
if not set(sub_list).intersection(set(merged_list[i])): # 1
merged_list.append(set()) # 2
i += 1 # 2
merged_list[i].update(set(sub_list)) # 3
return [sorted(sub_list) for sub_list in merged_list] # 4
mylist=[[1,2,3],[3,4,5],[5,6],[6,7],[9,10],[10,11]]
print merge_containing(mylist)
Output:
[[1, 2, 3, 4, 5, 6, 7], [9, 10, 11]]
How does it work:
Check if the sub_list set shares any common member with the current
index set of the merged_list.
If it doesn't, add a new empty set to the merged_list and increment
the index.
Adds the sub_list set to the set at index in the merged_list.
Converts from set to list and return
def merge(list_of_lists):
number_set = set()
for l in list_of_lists:
for item in l:
number_set.add(item)
return sorted(number_set)
if __name__ == '__main__':
list_of_lists = [[1,2,3],[3,4,5],[5,6],[6,7],[9,10],[10,11]]
merged = merge(list_of_lists)
print merged
I'm posting this as a new answer since the OP already accepted my other.
But as pointed out by #Eithos,
the input:
[[3,4], [1,2], [1,3]]
should return
[[1,2,3,4]]
and the input
[[1,2,3],[3,4,5],[5,6],[6,7],[9,10],[10,11],[65,231,140], [13,14,51]]
should return
[[1, 2, 3, 4, 5, 6, 7], [9, 10, 11], [13, 14], [51], [65], [140], [231]]
Here's my attempt:
from itertools import chain
def merge_containing(input_list):
print " input:", input_list
chain_list = sorted(set(chain(*input_list))) # 1
print " chain:",chain_list
return_list = []
new_sub_list = []
for i, num in enumerate(chain_list):
try:
if chain_list[i + 1] == chain_list[i] + 1: # 2
new_sub_list.append(num)
else:
new_sub_list.append(num) # 3
return_list.append(new_sub_list)
new_sub_list = []
except IndexError:
new_sub_list.append(num) # 3
return_list.append(new_sub_list)
print 'result:', return_list
return return_list
mylist = [[3,4], [1,2], [1,3]]
merge_containing(mylist)
print
mylist = [[1,2,3],[3,4,5],[5,6],[6,7],[9,10],[10,11],[65,231,140], [13,14,51]]
merge_containing(mylist)
Output:
input: [[3, 4], [1, 2], [1, 3]]
chain: [1, 2, 3, 4]
result: [[1, 2, 3, 4]]
input: [[1, 2, 3], [3, 4, 5], [5, 6], [6, 7], [9, 10], [10, 11], [65, 231, 140], [13, 14, 51]]
chain: [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 14, 51, 65, 140, 231]
result: [[1, 2, 3, 4, 5, 6, 7], [9, 10, 11], [13, 14], [51], [65], [140], [231]]
Explanation:
This one is a little hacky them the last one
I use itertool.chain to flat all the lists and them I sort it.
Then I check if the current number is within the range of 1 digit from the next
If it is I store it in the new_sub_list, if not I store in the new_sub_list, then store new_sub_list in the return_list, and empty the new_sub_list.
Note the try/except Index Error, it to avoid comparing the last item of the list with one that doesn't exist,
Well... I couldn't resist answering #f.rodrigues' last answer with one of my own.
I have to be honest though, this final version was heavily influenced by jonrsharpe's solution (the code went through various revisions, each one more efficient until I realized his method was the only way to press the most amount of juice) over here: Using sublists to create new lists where numbers don't repeat
Which made me wonder... why are we answering the same question over and over again (from the very same person)? This question, how to merge two sublists sharing any number in common? and the one with jonrsharpe's solution.
Anyway, this joins lists in the way outlined in his first question, but, like the solutions he already received over there, this one also works just as well for solving this problem.
sequence = [[1, 4, 9], [2, 3, 6], [4, 13, 50], [13, 23, 29], [2, 3, 7]]
def combineSequences(seq):
for index, y in enumerate(seq):
while True:
for x in seq[index + 1:]:
if any(i in x for i in seq[index]):
seq.remove(x)
y.extend(x)
break
else:
index += 1
break
return [sorted(set(l)) for l in seq]
sequence = [[1, 4, 9], [2, 3, 6], [4, 13, 50], [13, 23, 29], [2, 3, 7]]
print combineSequences(sequence)
>>> [[1, 4, 9, 13, 23, 29, 50], [2, 3, 6, 7]]
sequence = [[3, 4], [1, 2], [1, 3]]
print combineSequences(sequence)
>>> [[1, 2, 3, 4]]
This solution operates under a different assumption than the one I made earlier, just to clarify. This simply joins lists that have a common number. If the idea, however, was to only have them separated by intervals of 1, see my other answer.
That's it!
Okay. This solution may be difficult to grasp at first, but it's quite logical and succint, IMO.
The list comprehension basically has two layers. The outer layer will itself create separate lists
for each value of i (outer index) that satisfies the condition that the value it points to in the list is not equal to the value pointed to by the previous index + 1. So every numerical jump greater than one will create a new list within the outer list comprehension.
The math around the second (inner list comprehension) condition is a bit more complicated to explain, but essentially the condition seeks to make sure that the inner list only begins counting from the point where the outer index is at, stopping to where once again there is a numerical jump greater than one.
Assuming an even more complicated input:
listVar=[[1,2,3],[3,4,5],[5,6],[6,7],[9,10],[10,11],[65,231,140], [13,14,51]]
# Flattens the lists into one sorted list with no duplicates.
l = sorted(set([x for b in listVar for x in b]))
lGen = xrange(len(l))
print [
[l[i2] for i2 in lGen if l[i2] + i == l[i] + i2]
for i in lGen if l[i] != l[i-1] + 1
]
>>> [[1, 2, 3, 4, 5, 6, 7], [9, 10, 11], [13, 14], [51], [65], [140], [231]]

How can I merge lists that have common elements within a list of lists?

I have a list like [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]. How can I get a list that contains lists of all the lists that contain overlapping elements added together? For the example input, the result should be [[1, 2, 4, 5], [0, 3, 6, 7, 8, 12], [14, 18]].
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
result = []
for s in a:
s = set(s)
for t in result:
if t & s:
t.update(s)
break
else:
result.append(s)
This will go one-by-one through the list and create a set from the current sublist (s). Then it will check in the results, if there is another set t that has a non-empty intersection with it. If that’s the case, the items from s are added to that set t. If there is no t with a non-empty intersection, then s is a new independent result and can be appended to the result list.
A problem like this is also a good example for a fixed-point iteration. In this case, you would look at the list and continue to merge sublists as long as you could still find lists that overlap. You could implement this using itertools.combinations to look at pairs of sublists:
result = [set(x) for x in a] # start with the original list of sets
fixedPoint = False # whether we found a fixed point
while not fixedPoint:
fixedPoint = True
for x, y in combinations(result, 2): # search all pairs …
if x & y: # … for a non-empty intersection
x.update(y)
result.remove(y)
# since we have changed the result, we haven’t found the fixed point
fixedPoint = False
# abort this iteration
break
One way I can think of doing this is through recursion. Start with one item, then loop until you find every number it's connected to. For each of these numbers, you must do the same. Hence the recursion. To make it more efficient, store numbers you've visited in a list and check it at the beginning of each recursive sequence to make sure you don't repeat any explorations.
A two liner:
a_set = [set(x) for x in a]
result = [list(x.union(y)) for i,x in enumerate(a_set) for y in a_set[i:]
if x.intersection(y) and x != y]
I have left the last step for you:
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
result = [[1, 2, 4, 5], [0, 3, 6, 7, 8, 12], [14, 18]]
# each sub list
result2 = []
count = 0
print a
for sub_list in a:
print count
print "sub_list: " + str(sub_list)
a.pop(count)
print "a: " + str(a)
#each int
sub_list_extend_flag = False
for int_in_sub_list in sub_list:
print "int_in_sub_list: " + str(int_in_sub_list)
for other_sub_list in a:
print "current_other_sub_list: " + str(other_sub_list)
if int_in_sub_list in other_sub_list:
sub_list_extend_flag = True
other_sub_list.extend(sub_list)
result2.append(list(set(other_sub_list)))
if not sub_list_extend_flag:
result2.append(sub_list)
count += 1
print result2
Simple answer:
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
for x in a:
for y in x:
print y
its more simple than first one:
box=[]
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
for x in a:
for y in x:
box.append(y)
print box
Result:[1, 2, 4, 2, 5, 0, 3, 7, 8, 12, 3, 6, 18, 14]
And with this, you can compare the numbers:
box=[]
box2=""
a = [[1, 2, 4], [2, 5], [0, 3, 7, 8], [12, 3, 6], [18, 14]]
for x in a:
for y in x:
box.append(y)
print box
for a in box:
box2+=str(a)
print box2
Result: 12425037812361814
Also you can make it more cute:
print " ".join(box2)
Result: 1 2 4 2 5 0 3 7 8 1 2 3 6 1 8 1 4

How to merge multiple arrays in pairs

I have a problem with "pairing" arrays into one (by index). Here is an example:
INPUT:
inputArray = [[0, 1, 2, 3, 4], [2, 3, 5, 7, 8], [9, 6, 1]]
EXPECTED OUTPUT:
outputArray =
[[0,2,9],
[1,3,6],
[2,5,1],
[3,7,chooseRandom()],
[4,8,chooseRandom()]]
Questions:
How to avoid "out of range" "index error" problem
How to write chooseRandom() to choose N neighbour
Answers:
[SOLVED] Solutions provided by #jonrsharpe & #Christian & #Decency works as
expected
Clarification:
By N neighbour I mean:
I'm using python but feel free to share your thoughts in any language.
I think the following will do what you want:
from itertools import izip_longest # 'zip_longest' in Python 3.x
from random import choice
# Step 1
outputArray = list(map(list, izip_longest(*inputArray)))
# Step 2
for index, arr in enumerate(outputArray):
if any(item is None for item in arr):
valid = [item for item in arr if item is not None]
outputArray[index] = [choice(valid) if item is None else item
for item in arr]
This has two steps:
Combine all sub-lists of inputArray to the length of the longest sub-array, filling with None: [[0, 2, 9], [1, 3, 6], [2, 5, 1], [3, 7, None], [4, 8, None]]; and
Work through the outputArray, finding any sub-lists that contain None and replacing the None with a random choice from the other items in the sub-list that aren't None.
Example output:
[[0, 2, 9], [1, 3, 6], [2, 5, 1], [3, 7, 3], [4, 8, 8]]
Here's my approach to the problem, in Python 3.4. I don't really know what you mean by "choose N neighbour" but it should be pretty easy to write that however you'd like in the context below.
inputArray = [[0, 1, 2, 3, 4], [2, 3, 5, 7, 8], [9, 6, 1]]
import itertools
zipped = itertools.zip_longest(*inputArray, fillvalue=None)
outputArray = [list(item) for item in zipped]
# [[0, 2, 9], [1, 3, 6], [2, 5, 1], [3, 7, None], [4, 8, None]]
# Now replace the sentinel None in our sublists
for sublist in outputArray:
for i, element in enumerate(sublist):
if element is None:
sublist[i] = chooseRandom()
print(outputArray)
Not the most pythonic way, but you could try using this code snipped, read the comments in the code below:
import itertools, random
inputArray = [ [0, 1, 2, 3, 4], [2, 3, 5, 7, 8], [9, 6, 1] ]
outputArray = []
max_length = max(len(e) for e in inputArray) # maximum length of the sublists in <inputArray>
i = 0 # to keep the index of sublists of <outputArray>
for j in range(max_length):
outputArray.append([]) # add new sublist
for e in inputArray: # iterate through each element of <inputArray>
try:
outputArray[i].append(e[j]) # try to append the number, if an exception is raised
# then the code in the <except> clause will be executed
except IndexError as e:
outputArray[i].append(random.randint(0, 10)) # add the random number
i += 1 # increase the sublists index on each iteration
print outputArray
# [[0, 2, 9], [1, 3, 6], [2, 5, 1], [3, 7, 3], [4, 8, 7]]
Note:
You may want to change the part
random.randint(0, 10)
to get the "N neighbour".
Let me know whether you like this code:
import random
array = [[0, 1, 2, 3, 4], [2, 3, 5, 7, 8], [9, 6, 1]]
max_len = max([len(l) for l in array])
dictionary = {}
for l in array:
for i in range(0,len(l)):
if dictionary.has_key(i):
dictionary[i].append(l[i])
else:
dictionary[i] = [l[i]]
for i in range(len(l),max_len):
if dictionary.has_key(i):
dictionary[i].append(random.choice(l))
else:
dictionary[i] = [random.choice(l)]
print dictionary.values()

Categories

Resources