在Python中,有没有一种方法可以使用foreach样式的构造来更新容器?
我假设在Python中,有没有一种方法可以使用foreach样式的构造来更新容器?,python,list,for-loop,foreach,containers,Python,List,For Loop,Foreach,Containers,我假设Python中的foreach样式构造允许我像在C#中一样更新列表。没有 经过一些调查,我发现foreach样式构造中的Python中使用的变量不是一个引用,而是一个单独的标量变量,因此我无法使用它更新容器。有没有办法使用foreach样式更新容器 下面是一些演示我的问题的代码: inputString = " Type X Widgets , 25, 14.20 , Type Y Widgets , 4 , 1.12 " inputList = inputString.spl
Python
中的foreach样式构造允许我像在C#
中一样更新列表。没有
经过一些调查,我发现foreach样式构造中的
Python
中使用的变量不是一个引用,而是一个单独的标量变量,因此我无法使用它更新容器。有没有办法使用foreach样式更新容器
下面是一些演示我的问题的代码:
inputString = " Type X Widgets , 25, 14.20 , Type Y Widgets , 4 , 1.12 "
inputList = inputString.split(',')
print(inputList) # Now I need to get rid of whitespace on the ends of each element
# The foreach-style does NOT update inputList
for element in inputList:
element = element.strip()
print(element, end=",") # element contains the stripped string as I wanted
print()
print(inputList) # the whitespace on the ends of the elements is still there
# The for-style with subscripts DOES update inputList
for i in range(len(inputList)):
inputList[i] = inputList[i].strip()
print(inputList[i], end=",") # inputList[i] contains the stripped string as I wanted
print()
print(inputList) # it finally contains the stripped strings with no whitespace on the ends
以下是上述内容的输出:
[' Type X Widgets ', ' 25', ' 14.20 ', ' Type Y Widgets ', ' 4 ', ' 1.12 ']
Type X Widgets,25,14.20,Type Y Widgets,4,1.12,
[' Type X Widgets ', ' 25', ' 14.20 ', ' Type Y Widgets ', ' 4 ', ' 1.12 ']
Type X Widgets,25,14.20,Type Y Widgets,4,1.12,
['Type X Widgets', '25', '14.20', 'Type Y Widgets', '4', '1.12']
第一个for循环不会更新容器。第二个是。在这个简单的例子中,我必须使用下标并不重要,但我真的希望能够在下标根本不起作用时使用foreach样式来更新更复杂的容器类型
我可以在
C#
中实现这一点,这是一个非常强大的工具。在Python
中,除了我在第一个循环中尝试的方法之外,是否还可以执行其他操作?(如果是这样的话,我想这将涉及到使用指针。Python
甚至有指针吗?也许这不是您想要的,但一个简单的方法是创建一个新列表,如下所示:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
这会将新列表分配给同一个变量,替换旧的变量(在此之后,旧的列表将被垃圾收集)
缺点是,这会使使用的内存量翻倍;完成上述语句后,可以对旧列表进行垃圾收集,但内存使用量仍会急剧增加。也许这不是您想要的,但一种简单的方法是创建一个新列表,如下所示:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
这会将新列表分配给同一个变量,替换旧的变量(在此之后,旧的列表将被垃圾收集)
缺点是,这会使使用的内存量翻倍;完成上述语句后,可以对旧列表进行垃圾收集,但内存使用率仍将出现峰值。在这种特定情况下,您不能这样做。这是因为您正在将对象重新指定给一个新的引用 在“foreach”类型的迭代中,如下所示:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
您正在遍历列表中元素本身的对象。但在本例中,它是一个不可变的str
对象。i、 e.当您尝试分配此行时:
element = element.strip()
您正在使用原始内容的剥离内容中的新对象重新指定元素。因为它是一个新对象,所以它与inputList
本身没有任何关系
但是,在第二个示例中,您现在正在迭代基于inputList
的索引列表:
for i in range(len(inputList)):
# range(len(inputList)) -> range(0, 6)
在遍历列表时,请注意,您再次指定了inputList
的特定索引:
inputList[i] = inputList[i].strip()
这会将一个新对象分配回inputList[i]
。它不再是列表中曾经的str
对象
话虽如此,在其他用例中,只要对象是可变的,您正在寻找的“foreach”就可以正常工作。观察以下示例:
lst = [[] for _ in range(5)]
lst
# [[], [], [], [], []]
for i in lst:
i.append('foo')
lst
# [['foo'], ['foo'], ['foo'], ['foo'], ['foo']]
请注意此处的差异:i
不是重新分配的,而是由append()
方法直接更改的。为了进一步证明i
是符合您期望的直接对象引用,如果我在迭代完成后这样做:
请参见如何添加lst
的最后一个元素。这是因为i
仍然保留引用。id()
如果我像这样编写迭代:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
lst中的i的:
i=['foo']
lst
# [[], [], [], [], []]
身份证(一)
#61354112在这种特殊情况下,您不能。这是因为您正在将对象重新指定给一个新的引用
在“foreach”类型的迭代中,如下所示:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
您正在遍历列表中元素本身的对象。但在本例中,它是一个不可变的str
对象。i、 e.当您尝试分配此行时:
element = element.strip()
您正在使用原始内容的剥离内容中的新对象重新指定元素。因为它是一个新对象,所以它与inputList
本身没有任何关系
但是,在第二个示例中,您现在正在迭代基于inputList
的索引列表:
for i in range(len(inputList)):
# range(len(inputList)) -> range(0, 6)
在遍历列表时,请注意,您再次指定了inputList
的特定索引:
inputList[i] = inputList[i].strip()
这会将一个新对象分配回inputList[i]
。它不再是列表中曾经的str
对象
话虽如此,在其他用例中,只要对象是可变的,您正在寻找的“foreach”就可以正常工作。观察以下示例:
lst = [[] for _ in range(5)]
lst
# [[], [], [], [], []]
for i in lst:
i.append('foo')
lst
# [['foo'], ['foo'], ['foo'], ['foo'], ['foo']]
请注意此处的差异:i
不是重新分配的,而是由append()
方法直接更改的。为了进一步证明i
是符合您期望的直接对象引用,如果我在迭代完成后这样做:
请参见如何添加lst
的最后一个元素。这是因为i
仍然保留引用。id()
如果我像这样编写迭代:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
lst中的i的:
i=['foo']
lst
# [[], [], [], [], []]
身份证(一)
#61354112Hhm。在for循环中,在每次迭代期间,变量(在case元素中)将分配给列表中下一个值(对象)的副本,而不是该值(对象)的引用。(这并不完全正确,但你知道我想说什么)。因此,为了解决您的项目,您可以做如下操作:
inputList = [
element.strip()
for element in inputList]
for element in inputList:
for i in lst:
i = ['foo']
lst
# [[], [], [], [], []]
id(i)
# 61354112 <-- different obj id
id(lst[-1])
# 61353816
for element in inputList:
inputList[inputList.index(element)] = element.strip()
print(inputList)
请注意,当列表中有相同元素两次时,这将不起作用
希望有帮助 Hhm。在for循环中,在每次迭代期间,您的变量(在