错误将列表混乱到新列表中

时间:2017-08-17 17:03:01

标签: python

我通过逐项移动旧列表 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]]

正确的值在迭代上打印,但最终列表具有所有相同的值。

3 个答案:

答案 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]]