qtd_packs = 2
size_pack = 16
pasta = []
pasta.append ('packs/krun/')
pasta.append ('packs/parting2/')
for k in range(0, qtd_packs):
for n in range(1, size_pack+1):
samples_in.append (pasta[k]+str(n)+'.wav')
samples.append(samples_in)
del samples_in[0:len(samples_in)]
print(samples)
我基本上是在samples_in
列表中添加samples
,然后删除旧samples_in
列表以创建新列表。这将发生2次,如qtd_packs =2
。但最后,我得到的是两个空列表:
[[], []]
我在append
内samples_in
删除了samples
之前删除它。那发生了什么?
谢谢
答案 0 :(得分:2)
在Python中,列表通过引用传递。将samples_in
追加到samples
时,Python会将samples_in
的引用附加到samples
。如果您要将samples_in
的副本附加到samples
,则可以执行以下操作:
samples.append(samples_in[:])
这有效地创建了samples_in
中所有项目的新列表,并将该新列表传递到samples.append()
。现在,当您清除samples_in
中的项目时,您也不会清除附加到samples
的列表中的项目。
另请注意,samples_in[:]
相当于samples_in[0:len(samples_in)]
。
答案 1 :(得分:1)
问题是在此之后:
samples.append(samples_in)
samples
中新添加的值不是samples_in
的副本,而是完全相同的值。您可以从交互式解释器中看到这一点:
>>> samples_in = [0]
>>> samples = []
>>> samples.append(samples_in)
>>> samples[-1] is samples_in
True
>>> id(samples[-1]), id(samples_in)
(12345678, 12345678)
使用interactive visualizer可能会让您更容易看到正在发生的事情。
因此,当您通过一个名称修改值时,如下所示:
>>> del samples_in[0:len(samples_in)]
通过两个名称可以看到相同的修改:
>>> samples[-1]
[]
一旦你意识到两个名字都指的是同一个值,那就应该是显而易见的了。
作为旁注,del samples_in[:]
与del samples_in[0:len(samples_in)]
完全相同,因为它们已经是切片的默认值。
如果您不希望这两个名称引用相同的值,该怎么办?然后你必须明确地复制。
copy
模块具有可以复制(几乎)任何内容的功能,但许多类型都有更简单的方法。例如,samples_in[:]
要求一个新列表,它将片段从0复制到结尾(同样,这些是默认值)。所以,如果你这样做了:
>>> samples.append(samples_in[:])
... samples[-1]
你会得到一个新值。同样,您可以轻松地测试:
>>> samples[-1], samples_in
([0], [0])
>>> samples[-1] == samples_in
True
>>> samples[-1] is samples_in
False
>>> id(samples[-1]), id(samples_in)
23456789, 12345678
如果你改变了一个值,那么它不会影响另一个 - 毕竟它们是单独的值:
>>> del samples_in[:]
>>> samples[-1], samples_in
([0], [])
然而,在这种情况下,你甚至不需要复制。您遇到问题的唯一原因是您尝试反复使用samples_in
。没有理由这样做,如果你每次只创建一个新的samples_in
值,问题就不会出现在第一位。而不是:
samples_in = []
for k in range(0, qtd_packs):
for n in range(1, size_pack+1):
samples_in.append (pasta[k]+str(n)+'.wav')
samples.append(samples_in)
del samples_in[0:len(samples_in)]
这样做:
for k in range(0, qtd_packs):
samples_in = []
for n in range(1, size_pack+1):
samples_in.append (pasta[k]+str(n)+'.wav')
samples.append(samples_in)
答案 2 :(得分:0)
qtd_packs = 2
size_pack = 16
pasta = []
pasta.append ('packs/krun/')
pasta.append ('packs/parting2/')
samples = []
samples_in = []
for k in range(0, qtd_packs):
for n in range(1, size_pack+1):
samples_in.append (pasta[k]+str(n)+'.wav')
samples.append(samples_in[:])
del samples_in[0:len(samples_in)]
print(samples)
生成此输出:
[['packs/krun/1.wav', 'packs/krun/2.wav', 'packs/krun/3.wav', 'packs/krun/4.wav',
'packs/krun/5.wav', 'packs/krun/6.wav', 'packs/krun/7.wav', 'packs/krun/8.wav',
'packs/krun/9.wav', 'packs/krun/10.wav', 'packs/krun/11.wav', 'packs/krun/12.wav',
'packs/krun/13.wav', 'packs/krun/14.wav', 'packs/krun/15.wav', 'packs/krun/16.wav'],
['packs/parting2/1.wav', 'packs/parting2/2.wav', 'packs/parting2/3.wav',
'packs/parting2/4.wav', 'packs/parting2/5.wav', 'packs/parting2/6.wav',
'packs/parting2/7.wav', 'packs/parting2/8.wav', 'packs/parting2/9.wav',
'packs/parting2/10.wav', 'packs/parting2/11.wav', 'packs/parting2/12.wav',
'packs/parting2/13.wav', 'packs/parting2/14.wav', 'packs/parting2/15.wav',
'packs/parting2/16.wav']]
现在,当我最初阅读您的问题时,我认为您正在尝试制作包含所有字符串的单个列表。在那种情况下,您可以使用
samples.extend(samples_in)
而不是
samples.append(samples_in[:])
你会得到一个只包含字符串的平面列表。