Error shuffling list into new list - python

I am creating a list by shifting an old list out_g, item by item, and appending the result to the new one, new_sets. As I am iterating, I check the resulting shift, and it is correct. After this is complete, I print out the new list, and it is all a single object repeated. What am I missing?
The error occurs during the for loop at the end, where I append the results to new_sets.
#!/usr/bin/python
import math
def LFSR(register, feedback, output):
"""
https://natronics.github.io/blag/2014/gps-prn/
:param list feedback: which positions to use as feedback (1 indexed)
:param list output: which positions are output (1 indexed)
:returns output of shift register:
"""
# calculate output
out = [register[i-1] for i in output]
if len(out) > 1:
out = sum(out) % 2
else:
out = out[0]
# modulo 2 add feedback
fb = sum([register[i-1] for i in feedback]) % 2
# shift to the right
for i in reversed(range(len(register[1:]))):
register[i+1] = register[i]
# put feedback in position 1
register[0] = fb
return out
def shiftInPlace(l, n):
# https://stackoverflow.com/questions/2150108/efficient-way-to-shift-a-list-in-python
n = n % len(l)
head = l[:n]
l[:n] = []
l.extend(head)
return l
##########
## Main ##
##########
n = 3
# init register states
if n == 5 :
LFSR_A = [1,1,1,1,0]
LFSR_B = [1,1,1,0,1]
LFSR_A_TAPS =[5,4,3,2]
LFSR_B_TAPS =[5,3]
elif n == 7:
LFSR_A = [1,0,0,1,0,1,0]
LFSR_B = [1,0,0,1,1,1,0]
LFSR_A_TAPS = [7,3,2,1]
LFSR_B_TAPS = [7,3]
elif n == 3:
LFSR_A = [1,0,1]
LFSR_B = [0,1,1]
LFSR_A_TAPS = [3,2]
LFSR_B_TAPS = [3,1]
output_reg = [n]
N = 2**n-1
out_g = []
for i in range(0,N): #replace N w/ spread_fact
a = (LFSR(LFSR_A, LFSR_A_TAPS, output_reg))
b = (LFSR(LFSR_B, LFSR_B_TAPS, output_reg))
out_g.append(a ^ b)
# FOR BALANCED GOLD CODES NUMBER OF ONES MUST BE ONE MORE THAN NUMBER
# OF ZEROS
nzeros = sum(x == 0 for x in out_g)
nones = sum(x == 1 for x in out_g)
print "Gold Code Output Period[%d] of length %d -- {%d} 0's, {%d} 1's" % (N,N,nzeros,nones)
# produce all time shifted versions of the code
new_sets = []
for i in range(0,N-1):
new_sets.append(shiftInPlace(out_g,1))
# a=shiftInPlace(out_g,1)
# new_sets.append(a)
print new_sets[i]
print new_sets
My output :
Gold Code Output Period[7] of length 7 -- {3} 0's, {4} 1's
[1, 1, 0, 1, 0, 1, 0]
[1, 0, 1, 0, 1, 0, 1]
[0, 1, 0, 1, 0, 1, 1]
[1, 0, 1, 0, 1, 1, 0]
[0, 1, 0, 1, 1, 0, 1]
[1, 0, 1, 1, 0, 1, 0]
[[1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0]]
Correct values are printing on the iteration, but the final list has all the same values.

The problem should be obvious from your output - you are seeing the same list because you are appending the same list. Consider - you even name your function "shift in place", so that returns a mutated version of the same list you passed in, and then you append that same list. So one quick fix is to make a copy which you end up appending:
new_sets = []
for i in range(0,N-1):
new_sets.append(shiftInPlace(out_g,1)[:]) # append copy
# a=shiftInPlace(out_g,1)
# new_sets.append(a)
print new_sets[i]
This gives the output:
Gold Code Output Period[7] of length 7 -- {3} 0's, {4} 1's
[1, 1, 0, 1, 0, 1, 0]
[1, 0, 1, 0, 1, 0, 1]
[0, 1, 0, 1, 0, 1, 1]
[1, 0, 1, 0, 1, 1, 0]
[0, 1, 0, 1, 1, 0, 1]
[1, 0, 1, 1, 0, 1, 0]
[[1, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 1], [1, 0, 1, 0, 1, 1, 0], [0, 1, 0, 1, 1, 0, 1], [1, 0, 1, 1, 0, 1, 0]]
As an aside, for efficient in-place rotations, consider changing your data-structure to a collections.deque, which implements a doubly-linked list:
In [10]: from collections import deque
...: d = deque([1, 1, 0, 1, 0, 1, 0])
...: print(d)
...: for i in range(0, N-1):
...: d.rotate(-1)
...: print(d)
...:
deque([1, 1, 0, 1, 0, 1, 0])
deque([1, 0, 1, 0, 1, 0, 1])
deque([0, 1, 0, 1, 0, 1, 1])
deque([1, 0, 1, 0, 1, 1, 0])
deque([0, 1, 0, 1, 1, 0, 1])
deque([1, 0, 1, 1, 0, 1, 0])
deque([0, 1, 1, 0, 1, 0, 1])

You might try creating your list of rotations like this:
>>> li=[1,0,1,1,0,0]
>>> [li[r:]+li[:r] for r in range(len(li))]
[[1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1], [1, 1, 0, 0, 1, 0], [1, 0, 0, 1, 0, 1], [0, 0, 1, 0, 1, 1], [0, 1, 0, 1, 1, 0]]

... following up on my comment to juanpa's answer ...
When you append in this fashion, you append a reference to the in-place list. Your two-line code with variable a works the same way. You've appended 6 copies of the same variable reference; every time you shift the list, you shift the underlying object. All of the appended references point to that object.
Here's detailed output tracing your program. Note how all of the elements of new_sets change on every iteration. In my repair, I used the two-line assignment, but added a copy like this: new_sets.append(a[:])
Gold Code Output Period[7] of length 7 -- {3} 0's, {4} 1's
TRACE out_g = [0, 1, 1, 0, 1, 0, 1]
ENTER shiftInPlace, l= [0, 1, 1, 0, 1, 0, 1]
LEAVE shiftInPlace, head= [0] l= [1, 1, 0, 1, 0, 1, 0]
TRACE a= [1, 1, 0, 1, 0, 1, 0] new_sets= [[1, 1, 0, 1, 0, 1, 0]]
TRACE out_g = [1, 1, 0, 1, 0, 1, 0]
ENTER shiftInPlace, l= [1, 1, 0, 1, 0, 1, 0]
LEAVE shiftInPlace, head= [1] l= [1, 0, 1, 0, 1, 0, 1]
TRACE a= [1, 0, 1, 0, 1, 0, 1] new_sets= [[1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1]]
TRACE out_g = [1, 0, 1, 0, 1, 0, 1]
ENTER shiftInPlace, l= [1, 0, 1, 0, 1, 0, 1]
LEAVE shiftInPlace, head= [1] l= [0, 1, 0, 1, 0, 1, 1]
TRACE a= [0, 1, 0, 1, 0, 1, 1] new_sets= [[0, 1, 0, 1, 0, 1, 1], [0, 1, 0, 1, 0, 1, 1], [0, 1, 0, 1, 0, 1, 1]]
TRACE out_g = [0, 1, 0, 1, 0, 1, 1]
ENTER shiftInPlace, l= [0, 1, 0, 1, 0, 1, 1]
LEAVE shiftInPlace, head= [0] l= [1, 0, 1, 0, 1, 1, 0]
TRACE a= [1, 0, 1, 0, 1, 1, 0] new_sets= [[1, 0, 1, 0, 1, 1, 0], [1, 0, 1, 0, 1, 1, 0], [1, 0, 1, 0, 1, 1, 0], [1, 0, 1, 0, 1, 1, 0]]
TRACE out_g = [1, 0, 1, 0, 1, 1, 0]
ENTER shiftInPlace, l= [1, 0, 1, 0, 1, 1, 0]
LEAVE shiftInPlace, head= [1] l= [0, 1, 0, 1, 1, 0, 1]
TRACE a= [0, 1, 0, 1, 1, 0, 1] new_sets= [[0, 1, 0, 1, 1, 0, 1], [0, 1, 0, 1, 1, 0, 1], [0, 1, 0, 1, 1, 0, 1], [0, 1, 0, 1, 1, 0, 1], [0, 1, 0, 1, 1, 0, 1]]
TRACE out_g = [0, 1, 0, 1, 1, 0, 1]
ENTER shiftInPlace, l= [0, 1, 0, 1, 1, 0, 1]
LEAVE shiftInPlace, head= [0] l= [1, 0, 1, 1, 0, 1, 0]
TRACE a= [1, 0, 1, 1, 0, 1, 0] new_sets= [[1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0]]
[[1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0]]

Related

Uniform distribution of array data

I have an array [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], and I would like to translate it into a uniform position, what would be the output get: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]. The array is not always of such length and the numbers in it can be in different proportions to each other, so the question arises how to do it dynamically and not manually?
Need help
This would work:
arr = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
counters = {}
for element in arr:
counters[element] = counters.get(element, 0) + 1
frequences = {k:len(arr)/float(v) for (k,v) in counters.items()}
progress = {k:0.0 for (k,v) in counters.items()}
result = []
for upperBound in range(len(arr)):
partial_result = {}
for (k,frequence) in frequences.items():
if(frequence * progress[k] < float(upperBound) + 0.5):
progress[k] = progress[k] + 1
partial_result[k] = frequence * progress[k] - float(upperBound)
for (k,v) in sorted(partial_result.items(), key=lambda item: item[1]):
result.append(k)
print(result)
First getting frequencies for each number, then going from 1 to len(arr) checking if accumulated frequency for each number is below this threshold, if so output this number and accumulate its frequency further.
Solution:
my_list = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
def make_uniform_list(the_list):
my_set = list(set(the_list))
size = len(the_list)/len(my_set)
new_list = []
for i in range(round(size)):
new_list += my_set
return new_list
Examples:
ex_1 = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
print(make_uniform_list(ex_1))
# [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
ex_2 = [0, 1, 1, 0, 1, 1, 1, 0, 0, 1]
print(make_uniform_list(ex_2))
# [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
ex_3 = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3]
print(make_uniform_list(ex_3))
# [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
I don't know if I get your question right. Is this code what you're looking for?
a = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
for e,i in enumerate(a): #finding the place where pattern is changed
if i!=a[0]:
divier_idx = e
break
result=[]
for i in zip(a[divier_idx:],a[:divier_idx]): #grouping data into needed formation
result.extend(i)
if len(a[divier_idx:]) != len(a[:divier_idx]): #in case if the sec part is longer than the first one by 1 item it is appended to the end
result.append(a[-1])
print(result)
# the output: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

Python 2d array loop

It might be stupid question but I'm starting with python and I have no clue how to write it.
So I want to print this table in loop like on the screen and then I want it to be usable but It's hard for me to write it down (look on screen pls):
table = [print([random.randint(0,1) for x in range(10)]) for y in range(10)]
a = table
print(a)
console output
The values are printed using the print inside the list. But the method print return nothing, None, so you're saving 10 None in the outer list
table = [[random.randint(0, 1) for x in range(10)] for y in range(10)]
for row in table:
print(row)
a = table
print(a)
[1, 0, 0, 1, 1, 0, 1, 1, 1, 1]
[0, 1, 1, 0, 0, 1, 0, 1, 1, 0]
[1, 0, 1, 0, 0, 0, 0, 1, 1, 0]
[1, 1, 1, 1, 0, 1, 1, 1, 0, 0]
[0, 1, 0, 0, 1, 1, 0, 1, 0, 0]
[1, 0, 0, 0, 0, 1, 0, 0, 0, 1]
[0, 1, 0, 1, 1, 1, 0, 0, 0, 0]
[0, 1, 0, 1, 0, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 1, 1, 1, 0, 1, 1]
[1, 1, 0, 0, 0, 0, 1, 1, 0, 0]
[[1, 0, 0, 1, 1, 0, 1, 1, 1, 1], [0, 1, 1, 0, 0, 1, 0, 1, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1, 1, 0], [1, 1, 1, 1, 0, 1, 1, 1, 0, 0], [0, 1, 0, 0, 1, 1, 0, 1, 0, 0], [1, 0, 0, 0, 0, 1, 0, 0, 0, 1], [0, 1, 0, 1, 1, 1, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 1, 1, 0, 1, 1], [1, 1, 0, 0, 0, 0, 1, 1, 0, 0]]

Turning a list into list of lists

I am writing a function which takes columns=c and rows=r (both can be unequal!) and that should a list of lists, where each row is a list containing c elements, all rows within a list. How do I create such sublists given the list below?
list = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
should return:
[[0, 0, 0, 0, 0], [1, 1, 0, 1, 1], [0, 0, 1, 1, 1], [1, 1, 1, 1, 0], [0, 1, 0, 1, 1]]
I tried to use split() however it seems like it works for strings only.
Numpy:
import numpy
c, r = 4, 5
list_ = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0]
numpy.array(list_).reshape(c, r).tolist()
#out (shortened example list to avoid 5x5):
[[0, 0, 0, 0, 0], [1, 1, 0, 1, 1], [0, 0, 1, 1, 1], [1, 1, 1, 1, 0]]
However, if your goal is to create "an cxr array with zeroes and ones", you should better use:
numpy.random.randint(0, high=2, size=(c, r))
# out
array([[1, 1, 1, 0, 0],
[1, 1, 0, 0, 0],
[0, 1, 1, 1, 0],
[1, 0, 0, 1, 0]])
Use itertools.islice: (Also don't use list as a variable name. It replaces the builtin function)
from itertools import islice
def chunker(data, rows, cols):
d = iter(data)
return [list(islice(d, cols)) for row in range(rows)]
data = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
result = chunker(data, 4, 5)
Result:
[[0, 0, 0, 0, 0],
[1, 1, 0, 1, 1],
[0, 0, 1, 1, 1],
[1, 1, 1, 1, 0]]
You can use a list comprehension:
c, r = 4, 5
list = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
list_of_lists = [list[i - c: i] for i in range(c, len(list), c)]
l= [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
print([L[i:i+4] for i in range(0,len(L),4)])
output:
[[0, 0, 0, 0], [0, 1, 1, 0], [1, 1, 0, 0], [1, 1, 1, 1], [1, 1, 1, 0], [0, 1, 0, 1], [1]]
using slicing and list comprehension.
new_list=[list[i:i+5] for i in range(len(list)//5)]
just do this like it,it will be done.
a sample usage screenshot
Try this:
ls = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1]
[ls[i*5:i*5+5] for i in range(len(ls)//5)]
Out[1]:
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 1, 0],
[0, 1, 1, 0, 1]]
Or as a function:
def split_list(list, length):
return [list[i*length:i*length+length] for i in range((len(list)//length))]
split_list(ls, 5)

Need a recursive function to get all permutations of an array where each element is itself plus 0 to n

Sorry for the wording of the title as I am unsure how to phrase the question.
I am trying to get all permutations of an array where each element could be it's value plus 0 to n ('wild' value)
e.g.
The array [0, 1, 0, 2, 1] with the wild value equal to 1 would have the permutations:
[1, 1, 0, 2, 1]
[0, 2, 0, 2, 1]
[0, 1, 1, 2, 1]
[0, 1, 0, 3, 1]
[0, 1, 0, 2, 2]
The array [1, 2, 0, 0] with the wild value equal to 2 would have the permutations:
[3, 2, 0, 0]
[2, 3, 0, 0]
[2, 2, 1, 0]
[2, 2, 0, 1]
[1, 4, 0, 0]
[2, 3, 0, 0]
[1, 3, 1, 0]
[1, 3, 0, 1]
[1, 2, 2, 0]
[2, 2, 1, 0]
[1, 3, 1, 0]
[1, 2, 1, 1]
... and so on...
This is the code I have tried, but it is not producing the desired results:
def generateAllMatrices(length, buckets, ind, wild):
if ind == length:
# possible_buckets.append(buckets.copy())
print(buckets)
return
if wild != 0:
for i in range(1, wild + 1):
buckets[ind] += 1
generateAllMatrices(length, buckets, 0, wild - 1)
buckets[ind] -= wild
generateAllMatrices(length, buckets, ind + 1, wild)
An example result produced from the above code is:
Original = [1, 0, 0, 2, 0, 1, 0, 0, 0, 1, 1, 0, 0]
Wild = 1
Permutations:
[2, 0, 0, 2, 0, 1, 0, 0, 0, 1, 1, 0, 0]
[1, 1, 0, 2, 0, 1, 0, 0, 0, 1, 1, 0, 0]
[1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 1, 0, 0]
[1, 0, 0, 3, 0, 1, 0, 0, 0, 1, 1, 0, 0]
[1, 0, 0, 2, 1, 1, 0, 0, 0, 1, 1, 0, 0]
[1, 0, 0, 2, 0, 2, 0, 0, 0, 1, 1, 0, 0]
[1, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 0, 0]
[1, 0, 0, 2, 0, 1, 0, 1, 0, 1, 1, 0, 0]
[1, 0, 0, 2, 0, 1, 0, 0, 1, 1, 1, 0, 0]
[1, 0, 0, 2, 0, 1, 0, 0, 0, 2, 1, 0, 0]
[1, 0, 0, 2, 0, 1, 0, 0, 0, 1, 2, 0, 0]
[1, 0, 0, 2, 0, 1, 0, 0, 0, 1, 1, 1, 0]
[1, 0, 0, 2, 0, 1, 0, 0, 0, 1, 1, 0, 1]
[1, 0, 0, 2, 0, 1, 0, 0, 0, 1, 1, 0, 0]
Are there any similar algorithms I could reference for this? Or what route should I take regarding developing something that will produce what I need.
Thanks!
You could do the following:
import itertools
def make_reps(l, wild):
for indices in itertools.product(range(len(l)), repeat=wild):
new_l = list(l)
for i in indices:
new_l[i] += 1
yield new_l
With your given examples:
In [12]: list(make_reps([0, 1, 0, 2, 1], 1))
Out[12]:
[[1, 1, 0, 2, 1],
[0, 2, 0, 2, 1],
[0, 1, 1, 2, 1],
[0, 1, 0, 3, 1],
[0, 1, 0, 2, 2]]
In [14]: list(make_reps([1, 2, 0, 0], 2))
Out[14]:
[[3, 2, 0, 0],
[2, 3, 0, 0],
[2, 2, 1, 0],
[2, 2, 0, 1],
[2, 3, 0, 0],
[1, 4, 0, 0],
[1, 3, 1, 0],
[1, 3, 0, 1],
[2, 2, 1, 0],
[1, 3, 1, 0],
[1, 2, 2, 0],
[1, 2, 1, 1],
[2, 2, 0, 1],
[1, 3, 0, 1],
[1, 2, 1, 1],
[1, 2, 0, 2]]

Permutation without duplicates in Python

I have N positions, and each position can be either 0 or 1. I have fixed number of 1s, and I want to permutate these fixed number of 1s in these N positions.
from itertools import permutations
p = [0 for k in xrange(6)]
for k in xrange(0,3):
p[k] = 1
print(list(permutations(p)))
But above result contains four [0,0,0,1,1,1] in the list. I only want one of them. How can I get rid of these duplicates?
You could grab the positions of the 1s instead:
from itertools import combinations
def place_ones(size, count):
for positions in combinations(range(size), count):
p = [0] * size
for i in positions:
p[i] = 1
yield p
In action:
>>> list(place_ones(6, 3))
[
[1, 1, 1, 0, 0, 0],
[1, 1, 0, 1, 0, 0],
[1, 1, 0, 0, 1, 0],
[1, 1, 0, 0, 0, 1],
[1, 0, 1, 1, 0, 0],
[1, 0, 1, 0, 1, 0],
[1, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 1, 0],
[1, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 0],
[0, 1, 1, 0, 0, 1],
[0, 1, 0, 1, 1, 0],
[0, 1, 0, 1, 0, 1],
[0, 1, 0, 0, 1, 1],
[0, 0, 1, 1, 1, 0],
[0, 0, 1, 1, 0, 1],
[0, 0, 1, 0, 1, 1],
[0, 0, 0, 1, 1, 1],
]
Set is perfect for this, as set does not not contain any duplicated element:
set(permutations(p))

Categories

Resources