如何更改嵌套列表中的元素?
Posted
技术标签:
【中文标题】如何更改嵌套列表中的元素?【英文标题】:How do I change an element in a nested list? 【发布时间】:2022-01-23 22:57:15 【问题描述】:我是 Python 初学者,需要一些建议。
我定义了十个变量,它们都有一个 X 和 Y 值。
然后我将这些变量(实际上是一个列表)放入另一个名为“pointlist”的列表中。
现在,我想使用 for 循环来更改每个变量的 X 值。
通常,我可以通过“pointlist[0][0]”访问第一个变量的X值。
当我将其应用于 for 循环时,出现以下错误: “TypeError:列表索引必须是整数或切片,而不是元组”
有人知道我错过了什么吗?提前非常感谢您!
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
【问题讨论】:
【参考方案1】:使用 Python 化你的循环:
for i in pointlist:
i[0] = random.randrange(limit1, limit2)
limit1-=100
limit2-=100
这样i
就变成pointlist
的一个入口,方便访问
【讨论】:
【参考方案2】:enumerate
调用在每个循环上返回一个元组,而不是单个值。因此,您的 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):
这里,_
是一个占位符,它采用 pointlist 值来防止 i
成为一个元组。第一个选项要好得多。
请注意,列表索引从 0 开始,而不是 1,因此您的 start=1
可能会破坏您的逻辑。使用默认起始值 0 可能会更好。
【讨论】:
【参考方案3】:您可能想要使用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
如果您仍想使用枚举。
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
【讨论】:
【参考方案4】:题外话。
添加到 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)
【讨论】:
非常感谢!尽管这是题外话,但您实际上帮助我解决了我遇到的完全不同的问题!我很感激!最好的问候。以上是关于如何更改嵌套列表中的元素?的主要内容,如果未能解决你的问题,请参考以下文章