我通过逐项移动旧列表 out_g 来创建列表,并将结果附加到新列表 new_sets 。当我在迭代时,我检查结果移位,这是正确的。完成后,我打印出新列表,重复所有单个对象。我错过了什么?
错误发生在 for 循环结束时,我将结果附加到 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
我的输出:
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]]
正确的值在迭代上打印,但最终列表具有所有相同的值。
答案 0 :(得分:4)
问题应该从您的输出中显而易见 - 您看到相同的列表,因为您要附加相同的列表。考虑一下 - 你甚至命名你的功能&#34;就地转移&#34;,这样就会返回你传入的同一个列表的变异版本,然后你追加相同的列表< / em>的。因此,一个快速解决方法是制作一份最终附加的副本:
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]
这给出了输出:
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]]
另外,对于有效的就地轮换,请考虑将数据结构更改为collections.deque
,它实现了双向链接列表:
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])
答案 1 :(得分:2)
您可以尝试创建这样的旋转列表:
>>> 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]]
答案 2 :(得分:2)
...跟进我对juanpa
的回答的评论......
以这种方式追加时,会附加对就地列表的引用。带变量a的双行代码的工作方式相同。您附加了相同变量引用的6个副本;每次移动列表时,都会移动基础对象。所有附加的引用都指向该对象。
这是跟踪程序的详细输出。请注意 new_sets 元素的所有在每次迭代时是如何变化的。在我的修复中,我使用了两行分配,但添加了这样的副本: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]]