将列表洗牌到新列表时出错

2024-05-16 00:59:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个列表,方法是将一个旧列表逐项移出,并将结果附加到新列表中。当我迭代时,我检查结果的移位,它是正确的。完成后,我打印出新的列表,它是所有单个对象的重复。我错过了什么

错误发生在末尾的for循环中,我将结果附加到新的\u集合中

#!/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]]

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


Tags: oftoinregister列表newforoutput
3条回答

问题应该从您的输出中显而易见-您看到的是相同的列表,因为您附加了相同的列表。考虑一下—您甚至将函数命名为“shift-in-place”,这样就可以返回您传入的同一列表的一个突变版本,然后您将同一列表追加到。因此,一个快速解决方法是制作一个副本,最后附加:

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])

。。。继续我对juanpa的回答的评论

以这种方式追加时,会向内建列表追加引用。带变量a的两行代码的工作方式相同。您已经附加了6个相同变量引用的副本;每次移动列表时,都会移动基础对象。所有附加的引用都指向该对象

下面是跟踪程序的详细输出。注意所有新集合的元素在每次迭代中是如何变化的。在我的修复中,我使用了两行赋值,但是添加了这样一个副本: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]]

您可以尝试创建如下旋转列表:

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

相关问题 更多 >