14

我有一个列表列表,列表中的每个列表包含 5 个项目,如何更改列表中项目的值?我尝试了以下方法:

    for [itemnumber, ctype, x, y, delay] in execlist:
        if itemnumber == mynumber:
            ctype = myctype
            x = myx
            y = myy
            delay = mydelay

最初我有一个元组列表,但我意识到我无法更改元组中的值,所以我切换到列表,但我仍然无法更改任何值。如果我从 for 循环中打印 ctype、x、y、delay、myctype、myx、myy 或 mydelay,则似乎一切正常,但如果我之后打印 execlist,我发现没有任何改变。

4

8 回答 8

17

问题是您正在创建列表的副本,然后修改副本。您要做的是修改原始列表。试试这个:

for i in range(len(execlist)):
    if execlist[i][0] == mynumber:
         execlist[i][1] = myctype
         execlist[i][2] = myx
         execlist[i][3] = myy
         execlist[i][4] = mydelay
于 2012-12-06T21:09:06.540 回答
3

您需要通过索引进行分配。假设您有一个列表列表,其中每个内部列表都有 5 个您描述的项目。如果您想遍历它们并更改每个内部列表中第二项的值,您可以执行以下操作:

l = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]
for i in l:
    i[1] = "spam"

print l
(output) [[0, "spam", 2, 3, 4], [5, "spam", 7, 8, 9], [10, "spam", 12, 13, 14]]
于 2012-12-06T21:08:33.500 回答
3

你可以使用enumerate()

for index, sublist in enumerate(execlist):
   if sublist[0] == mynumber:
       execlist[index][1] = myctype
       execlist[index][2] = myx
       execlist[index][3] = myy
       execlist[index][4] = mydelay
       # break

您可以删除#ifexeclist最多包含一个子列表,其第一项可以等于mynumber; 否则,您将无用地循环遍历列表的其余部分。

如果itemnumbers事实上是独一无二的,你可能最好使用字典或至少一个OrderedDict,这取决于你打算对你的数据做什么。

于 2012-12-06T21:08:41.187 回答
1

变量解包似乎没有传递引用,而是复制了值。一个解决方案是这样做:

foo = [[1, "gggg"], [3, "zzzz"]]

for item in foo:
    item[0] = 2
    item[1] = "ffff"

print(foo)

>>>> [[2, 'ffff'], [2, 'ffff']] 
于 2012-12-06T21:08:36.603 回答
0

不要在列表中分配局部变量。在循环

for i in lis:
    i = 5

只需将变量设置i为 5 并保持列表的实际内容不变。相反,您必须直接分配它:

for i in range(len(lis)):
     lis[i] = 5

这同样适用于列表列表,尽管在这种情况下不必分配局部变量,因此您可以使用该for...in构造。

for i in listoflists:
     for i2 in range(len(i)):
          i[i2] = 5 #sets all items in all lists to 5
于 2012-12-06T21:10:55.650 回答
0

更改在 中分配的变量for不会更改列表。这是一种相当易读的方法来做你想做的事:

execlist = [
    #itemnumber, ctype, x, y, delay
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10],
    [11, 12, 13, 14, 15],
]

mynumber, myctype, myx, myy, mydelay = 6, 100, 101, 102, 104

for i, sublist in enumerate(execlist):
   if sublist[0] == mynumber:
        execlist[i] = [mynumber, myctype, myx, myy, mydelay]

print execlist

输出:

[[1, 2, 3, 4, 5], [6, 100, 101, 102, 104], [11, 12, 13, 14, 15]]
于 2012-12-06T21:21:13.967 回答
0

迭代器变量是原始变量的副本(Python 本身没有引用的概念,尽管列表等结构是通过引用来引用的)。您需要执行以下操作:

for item in execlist:
    if item[0] == mynumber:
        item[1] = ctype
        item[2] = myx
        item[3] = myy
        item[4] = mydelay

item它本身也是一个副本,但它是对原始嵌套列表的引用的副本,因此当您引用其元素时,原始列表会被更新。

这不方便,因为您没有名字;也许字典或类会是更方便的结构。

于 2012-12-06T21:22:29.743 回答
0

这是我最近使用的一个例子,它是一个真正的心灵弯曲,但希望它可以帮助一些人!

pivot_peaks 是 pandas 数据帧的列表,其中一些是重复的。

# Create a new list with only a single entry for each item
new_list = []

for obj_index, obj in enumerate(pivot_peaks):
    add_new_frame = False

    if len(new_list) == 0:
        new_list.append(obj)
    else:
        for item in new_list:
            if item.equals(obj):
                add_new_frame = False
                break
            else:
                add_new_frame = True

        if add_new_frame == True:
            new_list.append(obj)
于 2020-02-28T19:49:44.767 回答