How to shuffle a list 6 times? - python

I want to shuffle a list 6 times but I keep getting the same result for all the 6 occasions. Can somebody help me find where the fault is?
Here is the code I used
import random
lis1=[0,1,2,3]
lis2=[]
for i in range(6):
random.shuffle(lis1)
lis2.append(lis1)
print lis2
And here is a sample result I got
[[1,3,2,0],[1,3,2,0],[1,3,2,0],[1,3,2,0],[1,3,2,0],[1,3,2,0]]
If I get jumbled lists, how can I sort them in ascending order? As in,I want to get this -
[[0,1,2,3],[2,3,1,0],[2,1,3,0],[1,0,3,2]]
into this-
[[0,1,2,3],[1,0,3,2],[2,1,3,0],[2,3,1,0]]

First, your code repeatedly inserts a lis1 reference into lis2. Since lis1 stays the same all this time, all of lis2 elements end up pointing to the same object. To fix this, you need to change the append() line to make a copy of the list each time:
lis2.append(lis1[:])
Now, to sort the result simply call sort() after the loop:
lis2.sort()

Try something simpler:
>>> first = [0,1,2,3]
>>> jumbled = [random.sample(first, len(first)) for i in range(6)]
>>> ordered = sorted(jumbled)
>>> jumbled
[[0, 3, 2, 1], [1, 0, 2, 3], [0, 2, 1, 3], [0, 1, 2, 3], [0, 2, 3, 1], [0, 3, 2, 1]]
>>> ordered
[[0, 1, 2, 3], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 2, 1], [0, 3, 2, 1], [1, 0, 2, 3]]

Store copy of lis1 not actual lis1
do this:
lis2.append(lis1[:])
Then code will be:
import random
lis1=[0,1,2,3]
lis2=[]
for i in range(6):
random.shuffle(lis1)
lis2.append(lis1[:])
print lis2
Output:
[[2, 3, 1, 0], [0, 3, 2, 1], [3, 0, 1, 2], [1, 2, 0, 3], [3, 0, 2, 1], [1, 0, 3, 2]]

import random
lis1=[0,1,2,3]
lis2=[]
for i in range(6):
r = random.randint(0,len(lis1))
#print(r)
lis2.append(lis1[r:]+lis1[:r])
print(lis2)
print(sorted(lis2))

Related

Inserting a value in a list of lists

My data is as follows,
data = [[2, 1, 2, 2], [2, 2, 1, 5], [1, 2, 2, 2], [2, 1, 2, 5], [2, 5, 2, 1]]
I would like to transform this such that there is a 0 at 0, 1, 2, 3 and 4th positions of the internal lists and get it look like below,
new_Data = [[0, 2, 1, 2, 2], [2, 0, 2, 1, 5], [1, 2, 0, 2, 2], [2, 1, 2, 0, 5], [2, 5, 2, 1, 0]]
I have tried using the following method,
a = 0
for n in range(len(mRco1)-1):
mRco1[n][n] = [a]
But it does not seem to work.
Can anyone suggest how can I go about this?
Use the list.insert() method
for i in range(len(data)):
data[i].insert(i, 0)
result :
print(data)
>>> [[0, 2, 1, 2, 2], [2, 0, 2, 1, 5], [1, 2, 0, 2, 2], [2, 1, 2, 0, 5], [2, 5, 2, 1, 0]]
You'd like to iterate over the lists in data, and for the n'th list, insert a 0 at position n. You can use the insert function for that, and define the following loop:
for i in range(len(data)):
data[i].insert(i, 0)

Python: How can I remove repeated-disordered sublists and monotonous sublists in a list of lists

I've seen some questions here very related but their answer doesn't work for me. I have a list of lists where 1) some sublists are repeated but their elements may be disordered, 2) and some sublists contain monotonous elements but of different lengths. For example
g = [[1, 2, 3], [3, 2, 1], [1, 1], [1, 1, 1], [1, 3, 2], [9, 0, 1], [4, 3, 2]]
The output should be, naturally according to my question:
g = [[1, 2, 3], [1, 1], [1, 1, 1], [9, 0, 1], [4, 3, 2]]
I've tried with set. It works for repeated-disordered sublists but it treats sublists with monotonous elements of different lengths as the same.
Use set + sorted tuples in a set comprehension
>>> g = {tuple(sorted(x)) for x in g}
{(0, 1, 9), (1, 1), (1, 1, 1), (1, 2, 3), (2, 3, 4)}
If you really need a list of lists as output, just transform through list comprehension
>>> g_list = [list(x) for x in g]
[[0, 1, 9], [1, 2, 3], [2, 3, 4], [1, 1, 1], [1, 1]]
Use a sorted tuple as your hash:
>>> g = [[1, 2, 3], [3, 2, 1], [1, 1], [1, 1, 1], [1, 3, 2], [9, 0, 1], [4, 3, 2]]
>>> result = []
>>> seen = set()
>>> for x in g:
... hsh = tuple(sorted(x))
... if hsh not in seen:
... result.append(x)
... seen.add(hsh)
...
>>> result
[[1, 2, 3], [1, 1], [1, 1, 1], [9, 0, 1], [4, 3, 2]]
If your sublists are small, this should be speedy enough, and at least the logic is clear.
If order doesn't matter, you could try this:
list(map(list,(set(map(lambda x: tuple(sorted(x)),g)))))
List Comprehension + Unpacking:
print([*{*[tuple(sorted(i)) for i in g]}])
Output:
[(0, 1, 9), (1, 2, 3), (2, 3, 4), (1, 1, 1), (1, 1)]
If you want the elements to be a list do:
print([list(i) for i in {*[tuple(sorted(i)) for i in g]}])
Output:
[[0, 1, 9], [1, 2, 3], [2, 3, 4], [1, 1, 1], [1, 1]]

How to calculate all the combinations of lists

I am blocked on a Python problem and hope someone could help me.
The problem is prety simple actually.
Im trying to build lists with all combination possible but the elements of the list have not the same range.
here is my code, I tried to do something with for loop but it doesnt work.
for j in range(0,size):
for k, val in enumerate(self.Algo.Inputs[j].Values):
self.Commandlist[j] = k
self.Commandlist is a list with fix range, and fill with zero at first.
self.Commandlist = [0,0,0]
self.Algo.Inputs[j].Values gives me the size of each elements, for example, if self.Algo.Inputs[0].Values = 4
self.Algo.Inputs[1].Values = 1
self.Algo.Inputs[2].Values = 2
i want all the combinations, [0,0,0],[1,0,0],[2,0,0],[3,0,0],[4,0,0],[0,1,0],[1,1,0],[2,1,0],[3,1,0],[4,1,0] etc..
I think I forgot a loop but i cant figure out. I tried some stuff with itertools module as well, but i cant make it work.
Thans for your help.
As mentioned you can use itertools, for example like that:
import itertools
a = b = c = range(3) # you can specify different range for each one
[list(x) for x in list(itertools.product(a, b, c))]
Result:
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0], [2, 2, 1], [2, 2, 2]]

How to write a lot of nested 'for' loops (Recursively)

word = "word"
# Splitting word into its characters
newword = []
for char in word:
newword.append(char)
print newword
#getting all permutations
test= []
for i in newword:
for j in newword:
if i != j:
for k in newword:
if j != k and i!= k:
for l in newword:
if i != l and j != l and k != l:
test.append(i+j+k+l)
print test
print type(test)
print len(test)
These 4 nested loops work nicely for 'word' because it has exactly 4 letters in it.
If I wanted as many 'for' loops as there are letters in any given word, how can I do this?
Any nice tricks?
In [10]: import itertools
In [11]: word = "word"
In [12]: test = [''.join(perm) for perm in itertools.permutations(word)]
In [13]: test
Out[13]:
['word',
'wodr',
'wrod',
'wrdo',
'wdor',
'wdro',
'owrd',
'owdr',
'orwd',
'ordw',
'odwr',
'odrw',
'rwod',
'rwdo',
'rowd',
'rodw',
'rdwo',
'rdow',
'dwor',
'dwro',
'dowr',
'dorw',
'drwo',
'drow']
This is a general recursive problem you are trying to solve. itertools already contains functions for practically all implementations you could possible need. However, if you want something to learn about, this is one way of doing it. I will permute a list of numbers. In this case, Ill find permutations for:
[0,1,2, ... ,N-1]
Note that once you have the permutations for the above, you can simply use these as the indices for permuting anything. So what is the general way of doing this?
Let us first look at the result for a specific case. For the case of say [0,1,2,3]. The result we are looking for is the list of lists:
[[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2],
[0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3], [1, 2, 3, 0],
[1, 3, 0, 2], [1, 3, 2, 0], [2, 0, 1, 3], [2, 0, 3, 1], [2, 1, 0, 3],
[2, 1, 3, 0], [2, 3, 0, 1], [2, 3, 1, 0], [3, 0, 1, 2], [3, 0, 2, 1],
[3, 1, 0, 2], [3, 1, 2, 0], [3, 2, 0, 1], [3, 2, 1, 0]]
The idea is to write a function that takes a single list of lists, and increment it. Consider the simple function:
def permNums(inp, N=4):
newInp = []
for i in inp:
for j in range(N):
if j not in i: newInp.append( i+[j] )
return newInp
Now execute this funciton with an empty list of lists ...
In [22]: permNums([[]])
Out[22]: [[0], [1], [2], [3]]
What happens when you run it again with its output?
In [23]: permNums(_)
Out[23]:
[[0, 1],
[0, 2],
[0, 3],
[1, 0],
[1, 2],
[1, 3],
[2, 0],
[2, 1],
[2, 3],
[3, 0],
[3, 1],
[3, 2]]
and repeat it again?
In [24]: permNums(_)
Out[24]:
[[0, 1, 2],
[0, 1, 3],
[0, 2, 1],
[0, 2, 3],
[0, 3, 1],
[0, 3, 2],
[1, 0, 2],
[1, 0, 3],
[1, 2, 0],
[1, 2, 3],
[1, 3, 0],
[1, 3, 2],
[2, 0, 1],
[2, 0, 3],
[2, 1, 0],
[2, 1, 3],
[2, 3, 0],
[2, 3, 1],
[3, 0, 1],
[3, 0, 2],
[3, 1, 0],
[3, 1, 2],
[3, 2, 0],
[3, 2, 1]]
Do it another time, and you will get the result you want.
Now you can consider the simple implementation:
result = [[]]
for i in range(N): result = permNums(_)
This will solve your problem (you just need to map the indices to your string, and join the result). However, this is not classical recursion. For recursion, there are two additional steps you need the perform.
Call the function within itself
Figure out when this calling-itself business is going to stop ...
Calling the function within itself is simple. Just replace
return newInp
with
return permNums(newInp, N)
This step should not be surprising because this is exactly what you did manually on the iPython console. However, you will need to stop at some point. In this specific case, the stopping criterion should be simple. If the number of elements in one of the inner lists == N, then stop.
So the modified program has two simple additions:
def permNums(inp, N=4):
if len(inp[0]) == N: return inp # stopping criterion
newInp = []
for i in inp:
for j in range(N):
if j not in i: newInp.append( i+[j] )
return permNums(newInp, N) # keep calling itself
print permNums([[]])
Hope this helps ...

Python combination and permuation code

I have following code to generate the set of combination, append the combination in the list, and return list.
def make_combination():
import itertools
max_range = 5
indexes = combinations_plus = []
for i in range(0, max_range):
indexes.append(i)
for i in xrange(2, max_range):
each_combination = [list(x) for x in itertools.combinations(indexes, i)]
combinations_plus.append(each_combination)
retrun combinations_plus
It generates so many combinations that I don't want (hard to display). But, I want the following combination:
1) [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
2) [[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
3) [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]]
I think problem in the following line but I don't know what it is. Any idea about what the mistake is.
combinations_plus.append(each_combination)
An easier way of doing what you want is the following:
list(list(itertools.combinations(list(range(5)), i)) for i in range(2, 5))
To fix your original code, there were two problems:
indexes = combinations_plus = []
The above creates two names for the exact same list. Appending to either appends to both which is not what you want.
The two for statements shouldn't be nested, or the list of indexes is incomplete:
for i in range(0, max_range):
indexes.append(i)
for i in xrange(2, max_range):
each_combination = [list(x) for x in itertools.combinations(indexes, i)]
combinations_plus.append(each_combination)
In fact, initialize indexes with range and skip the first for loop:
indexes = range(max_range) # becomes [0,1,2,3,4]
combinations_plus = []
With these fixes (and fixing the spelling of return, you have:
def make_combination():
import itertools
max_range = 5
indexes = range(max_range)
combinations_plus = []
for i in xrange(2, max_range):
each_combination = [list(x) for x in itertools.combinations(indexes, i)]
combinations_plus.append(each_combination)
return combinations_plus
Which returns (newlines added for readability):
[[[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]],
[[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]],
[[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]]]

Categories