在Python3中追加到循环内的列表(再次)

w1e3prcc  于 2023-02-10  发布在  Python
关注(0)|答案(1)|浏览(123)

我在迭代添加列表时遇到困难。
以下是MWE:

# Given a nested list of values, or sets
sets = [[1, 2, 3], [1, 2, 4], [1, 2, 5]]
    
# add a value to each sublist giving the number of that set in the list.
n_sets = len(sets)
for s in range(n_sets):
    (sets[s]).insert(0, s)

# Now repeat those sets reps times
reps = 4
expanded_sets = [item for item in sets for i in range(reps)]

# then assign a repetition number to each occurance of a set.
rep_list = list(range(reps)) * n_sets
for i in range(n_sets * reps):
    (expanded_sets[i]).insert(0, rep_list[i])
    
expanded_sets

其返回

[[3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 0, 1, 2, 3],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 1, 1, 2, 4],
 [3, 2, 1, 0, 2, 1, 2, 5],
 [3, 2, 1, 0, 2, 1, 2, 5],
 [3, 2, 1, 0, 2, 1, 2, 5],
 [3, 2, 1, 0, 2, 1, 2, 5]]

而不是期望的

[[0, 0, 1, 2, 3],
 [1, 0, 1, 2, 3],
 [2, 0, 1, 2, 3],
 [3, 0, 1, 2, 3],
 [0, 1, 1, 2, 4],
 [1, 1, 1, 2, 4],
 [2, 1, 1, 2, 4],
 [3, 1, 1, 2, 4],
 [0, 2, 1, 2, 5],
 [1, 2, 1, 2, 5],
 [2, 2, 1, 2, 5],
 [3, 2, 1, 2, 5]]

为了好玩,第一个循环返回一个期望值sets

[[0, 1, 2, 3], [1, 1, 2, 4], [2, 1, 2, 5]]

但是在第二循环sets改变为

[[3, 2, 1, 0, 0, 1, 2, 3], [3, 2, 1, 0, 1, 1, 2, 4], [3, 2, 1, 0, 2, 1, 2, 5]]

我怀疑这个问题与拷贝和引用有关,我试过在不同的地方添加.copy()和切片,但是对于索引子列表,我没有遇到一个有效的组合,我运行的是Python 3.10.6。
感谢您的关注!
根据建议的解决方案,[list(range(reps)) for _ in range(n_sets)]不能正确地替换list(range(reps)) * n_sets,因为它给出了[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]而不是所需的[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]。我需要扁平化吗?或者是否有一个带有_表示法的语法可以给我一个列表?
进一步更新...替换

rep_list = list(range(reps)) * n_sets

rep_list_nest = [list(range(reps)) for _ in range(n_sets)]
rep_list = [i for sublist in rep_list_nest for i in sublist]

对于expanded_sets给出相同的不期望结果。

qv7cva1a

qv7cva1a1#

问题就在这里:

expanded_sets = [item 
                 for item in sets
                 for i in range(reps)]

现在,这个列表在一行中包含sets的同一个元素四次,然后是重复四次的下一个元素,依此类推。
创建item的副本可修复此问题:

expanded_sets = [item.copy() 
                 for item in sets
                 for i in range(reps)]

在线试用
如果你想要一个更像Python的方法,那么要认识到结果是两个范围的乘积,并且你的原始sets都连接在一起:

from itertools import product

sets = [[1, 2, 3], [1, 2, 4], [1, 2, 5]]

expanded_sets = [[inner_counter, outer_counter] + sets_elem
                  for sets_elem, outer_counter, inner_counter in product(sets, range(len(sets)), range(4))]

在线试用

相关问题