如何更改嵌套列表中的元素?

How do I change an element in a nested list?

我是 Python 初学者,需要一些建议。

我定义了十个变量,它们都有一个 X 和 Y 值。

然后我将这些变量(实际上是一个列表)放在另一个名为“pointlist”的列表中。

现在,我想使用 for 循环来更改每个变量的 X 值

通常,我可以通过“pointlist[0][0]”访问第一个变量的X值。

当我将其应用于 for 循环时,出现以下错误: “类型错误:列表索引必须是整数或切片,而不是元组”

有人知道我错过了什么吗?提前致谢!

import random 
X=1350
Y=250

p1=[X, Y]
p2=[X, Y]
p3=[X, Y]
p4=[X, Y]
p5=[X, Y]
p6=[X, Y]
p7=[X, Y]
p8=[X, Y]
p9=[X, Y]
p10=[X, Y]
p11=[X, Y]
pointlist = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11]

limit1=1150
limit2=1250

for i in enumerate (pointlist, start=1):
    pointlist[i][0] = random.randrange(limit1, limit2)
    limit1-=100
    limit2-=100

您可能想使用 range 而不是 enumerate

import random 
X=1350
Y=250

p1=[X, Y]
p2=[X, Y]
p3=[X, Y]
p4=[X, Y]
p5=[X, Y]
p6=[X, Y]
p7=[X, Y]
p8=[X, Y]
p9=[X, Y]
p10=[X, Y]
p11=[X, Y]
pointlist = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11]

limit1=1150
limit2=1250

for i in range(len(pointlist)):
    pointlist[i][0] = random.randrange(limit1, limit2)
    limit1-=100
    limit2-=100

如果您仍想使用 enumerate

import random 
X=1350
Y=250

p1=[X, Y]
p2=[X, Y]
p3=[X, Y]
p4=[X, Y]
p5=[X, Y]
p6=[X, Y]
p7=[X, Y]
p8=[X, Y]
p9=[X, Y]
p10=[X, Y]
p11=[X, Y]
pointlist = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11]

limit1=1150
limit2=1250

for i in enumerate(pointlist, start=0):
    index = i[0] # get the index from here.
    value = i[1]
    pointlist[index][0] = random.randrange(limit1, limit2)
    limit1-=100
    limit2-=100

enumerate 在每个循环中调用 returns 一个元组,而不是单个值。因此,您的 i 被设置为一个元组,它由索引(从 1 开始)和点列表中的元素组成。您可以通过多种方式解决这个问题。一是改:

for i in enumerate(pointlist, start=1):

至:

for i in range(len(pointlist), start=1):

或者您可以保留 enumerate 调用并删除 pointlist 的返回元素,这实际上没有多大意义,但它是一个选项:

for i, _ in enumerate(pointlist, start=1):

这里,_ 是一个占位符,它采用点列表值来防止 i 成为元组。第一个选项要好得多。

请注意,列表索引从 0 开始,而不是 1,因此您 start=1 可能会破坏您的逻辑。使用默认起始值​​ 0 可能会好得多。

Python 化你的循环使用:

for i in pointlist:
    i[0] = random.randrange(limit1, limit2)
    limit1-=100
    limit2-=100

这样 i 就成为 pointlist 的条目,方便访问

题外话

添加到 Mat 的惊人答案:

我相信您明确创建了 p1...p11 因此当您更改一个点的 x 坐标时,其他点不会受到影响。如果您不打算使用参考 p1...p11,我建议使用 list comprehension:

point_list = [[X, Y] for _ in range(11)]

内部列表[X, Y]创建了11次,它们是11个独立的对象,所以改变其中的任何一个都不会影响其他的。您可以使用 Python Tutor.

将其可视化

在您的案例中,我个人更喜欢使用自定义对象而不是处理嵌套列表,因为它可以更好地显示代码的意图。这是我的编码方式:

import random

class Coordinate:
    """
    A container that represents a coordinate point.
    Functions to manipulate the coordinates (called methods)
    can be added here.
    You can optionally convert it to a dataclass using
    functools.dataclass decorator to clean up the code further.
    """

    def __init__(self, x: float, y: float) -> None:
        """ At creation of the Coordinate object,
        we set its x, y-coordinate values. """
        self.x = x
        self.y = y
    
    def __repr__(self) -> str:
        """ Defines how a Coordinate should be represented as a string."""
        return f'Coordinate({self.x}, {self.y})'

X = 1350
Y = 250

coords = [Coordinate(X, Y) for _ in range(11)]

lower_bound = 1150
upper_bound = 1250

for coord in coords:
    # Here we are saying we want to change the x-coordinate,
    # instead of the ambiguous coord[0] = ...
    coord.x = random.randrange(1150, 1250)
    lower_bound -= 100
    upper_bound -= 100

print(coords)