Python - 列表中的列表(可变性)
Python - List in a list (mutability)
我已经阅读了很多关于 Python 列表中列表的问题,但我仍然无法真正解决我面临的问题。
我尝试尽可能地简化我的代码,我将尝试解释我期望的结果。
我的代码:
import copy
class Location():
def __init__(self):
self.a_location_variable = 'a string'
self.a_location_list = []
def parse_row(self, sline):
self.a_location_variable = sline
def add_drop(self, drop):
self.a_location_list.append(copy.copy(drop))
class Drop():
def __init__(self):
self.a_drop_variable = 'also a string'
def parse_drop(self, sline):
self.a_drop_variable = sline
file = open('example.txt', 'r')
lines = file.read().split('\n')
loc = Location()
loc_list = []
drop = Drop()
all_drops = []
for i in range(40, len(lines)):
if lines[i][:4] == '5280':
loc.parse_row(lines[i])
loc_list.append(copy.copy(loc))
elif lines[i][:4] == '5301':
continue
elif lines[i][:4] == '5302':
continue
elif lines[i][:4] == '5303':
continue
else:
drop.parse_drop(lines[i])
loc_list[-1].add_drop(drop)
example.txt 的内容存在 40 header 行,然后从第 41 行开始:
5280,0, 0,+52.1216717,+004.3834450, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24800,1,1,"R ",2017,06,22,02,17
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 22.5, 23.7
1, 0686, 222.0, 187.0, 170.0, 148.0, 133.0, 99.0, 75.0, 58.0, 44.0, 27.300
2, 0680, 219.0, 186.0, 169.0, 147.0, 133.0, 98.0, 74.0, 58.0, 43.0, 27.420
3, 0680, 218.0, 185.0, 168.0, 146.0, 132.0, 98.0, 74.0, 58.0, 42.0, 27.410
4, 0678, 216.0, 183.0, 167.0, 145.0, 131.0, 98.0, 73.0, 58.0, 42.0, 27.460
5280,0, 0,+52.1217967,+004.3834800, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24775,1,1,"M ",2017,06,22,02,18
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 22.8, 23.6
1, 0699, 203.0, 157.0, 134.0, 108.0, 95.0, 70.0, 54.0, 45.0, 34.0, 27.190
2, 0704, 204.0, 157.0, 135.0, 109.0, 96.0, 71.0, 55.0, 45.0, 35.0, 27.300
3, 0699, 203.0, 157.0, 135.0, 109.0, 96.0, 71.0, 55.0, 45.0, 35.0, 27.200
4, 0702, 202.0, 156.0, 134.0, 108.0, 96.0, 70.0, 54.0, 45.0, 35.0, 27.480
5280,0, 0,+52.1217967,+004.3834800, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24750,1,1,"R ",2017,06,22,02,19
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 22.8, 23.5
1, 0688, 226.0, 177.0, 155.0, 130.0, 115.0, 84.0, 63.0, 51.0, 38.0, 27.430
2, 0692, 224.0, 175.0, 154.0, 129.0, 115.0, 84.0, 63.0, 51.0, 39.0, 27.420
3, 0689, 223.0, 175.0, 154.0, 129.0, 115.0, 84.0, 63.0, 51.0, 39.0, 27.530
4, 0690, 223.0, 175.0, 154.0, 129.0, 116.0, 84.0, 63.0, 51.0, 38.0, 27.510
5280,0, 0,+52.1219608,+004.3839767, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24724,1,1,"M ",2017,06,22,02,20
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 23.0, 23.6
1, 0700, 287.0, 208.0, 169.0, 130.0, 110.0, 75.0, 55.0, 44.0, 35.0, 27.350
2, 0700, 280.0, 203.0, 166.0, 128.0, 108.0, 74.0, 53.0, 42.0, 32.0, 27.280
3, 0697, 280.0, 204.0, 167.0, 130.0, 110.0, 76.0, 55.0, 44.0, 35.0, 27.410
4, 0698, 279.0, 203.0, 166.0, 129.0, 109.0, 75.0, 55.0, 44.0, 34.0, 27.340
每次代码找到以 5280 开头的行时,都会到达一个新位置。因此,我期望的结果是 loc_list,包含 4 个项目(class Location())。然后每个位置应该包含 'a_location_list',其中包含来自 class Drop() 的相应 4 行的信息。
这有效,但是,现在这里是我无法解决的问题:'loc_list' 中的每个位置都包含相同的 'a_location_list',包含来自所有 16 行的信息'Drop' 信息(以“1”、“2”等开头)而不仅仅是属于该位置的 4。
我不能把矛头指向这里的问题,所以有没有人可以帮助我解决这个问题?
我尽量简化了它。
好的,我继续搜索和阅读其他有类似问题的人,最后我自己找到了解决方案。
问题是我没有复制 'a_location_list'。
在classlocation()我修改了
def add_drop(self, drop):
self.a_location_list.append(copy.copy(drop))
到
def add_drop(self, drop):
self.a_location_list = self.a_location_list[:]
self.a_location_list.append(copy.copy(drop))
这使代码如我所愿。对于任何试图帮助我的人:无论如何谢谢!我希望通过在这里发布我自己的解决方案,其他人也能从中得到帮助。
我已经阅读了很多关于 Python 列表中列表的问题,但我仍然无法真正解决我面临的问题。
我尝试尽可能地简化我的代码,我将尝试解释我期望的结果。
我的代码:
import copy
class Location():
def __init__(self):
self.a_location_variable = 'a string'
self.a_location_list = []
def parse_row(self, sline):
self.a_location_variable = sline
def add_drop(self, drop):
self.a_location_list.append(copy.copy(drop))
class Drop():
def __init__(self):
self.a_drop_variable = 'also a string'
def parse_drop(self, sline):
self.a_drop_variable = sline
file = open('example.txt', 'r')
lines = file.read().split('\n')
loc = Location()
loc_list = []
drop = Drop()
all_drops = []
for i in range(40, len(lines)):
if lines[i][:4] == '5280':
loc.parse_row(lines[i])
loc_list.append(copy.copy(loc))
elif lines[i][:4] == '5301':
continue
elif lines[i][:4] == '5302':
continue
elif lines[i][:4] == '5303':
continue
else:
drop.parse_drop(lines[i])
loc_list[-1].add_drop(drop)
example.txt 的内容存在 40 header 行,然后从第 41 行开始:
5280,0, 0,+52.1216717,+004.3834450, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24800,1,1,"R ",2017,06,22,02,17
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 22.5, 23.7
1, 0686, 222.0, 187.0, 170.0, 148.0, 133.0, 99.0, 75.0, 58.0, 44.0, 27.300
2, 0680, 219.0, 186.0, 169.0, 147.0, 133.0, 98.0, 74.0, 58.0, 43.0, 27.420
3, 0680, 218.0, 185.0, 168.0, 146.0, 132.0, 98.0, 74.0, 58.0, 42.0, 27.410
4, 0678, 216.0, 183.0, 167.0, 145.0, 131.0, 98.0, 73.0, 58.0, 42.0, 27.460
5280,0, 0,+52.1217967,+004.3834800, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24775,1,1,"M ",2017,06,22,02,18
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 22.8, 23.6
1, 0699, 203.0, 157.0, 134.0, 108.0, 95.0, 70.0, 54.0, 45.0, 34.0, 27.190
2, 0704, 204.0, 157.0, 135.0, 109.0, 96.0, 71.0, 55.0, 45.0, 35.0, 27.300
3, 0699, 203.0, 157.0, 135.0, 109.0, 96.0, 71.0, 55.0, 45.0, 35.0, 27.200
4, 0702, 202.0, 156.0, 134.0, 108.0, 96.0, 70.0, 54.0, 45.0, 35.0, 27.480
5280,0, 0,+52.1217967,+004.3834800, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24750,1,1,"R ",2017,06,22,02,19
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 22.8, 23.5
1, 0688, 226.0, 177.0, 155.0, 130.0, 115.0, 84.0, 63.0, 51.0, 38.0, 27.430
2, 0692, 224.0, 175.0, 154.0, 129.0, 115.0, 84.0, 63.0, 51.0, 39.0, 27.420
3, 0689, 223.0, 175.0, 154.0, 129.0, 115.0, 84.0, 63.0, 51.0, 39.0, 27.530
4, 0690, 223.0, 175.0, 154.0, 129.0, 116.0, 84.0, 63.0, 51.0, 38.0, 27.510
5280,0, 0,+52.1219608,+004.3839767, 91.7, 4, 10, 100, 0.9
5301,2,1,4,2, 24724,1,1,"M ",2017,06,22,02,20
5302,0,0,A,p,0,1,0,0,
5303,0, 18.0, 23.0, 23.6
1, 0700, 287.0, 208.0, 169.0, 130.0, 110.0, 75.0, 55.0, 44.0, 35.0, 27.350
2, 0700, 280.0, 203.0, 166.0, 128.0, 108.0, 74.0, 53.0, 42.0, 32.0, 27.280
3, 0697, 280.0, 204.0, 167.0, 130.0, 110.0, 76.0, 55.0, 44.0, 35.0, 27.410
4, 0698, 279.0, 203.0, 166.0, 129.0, 109.0, 75.0, 55.0, 44.0, 34.0, 27.340
每次代码找到以 5280 开头的行时,都会到达一个新位置。因此,我期望的结果是 loc_list,包含 4 个项目(class Location())。然后每个位置应该包含 'a_location_list',其中包含来自 class Drop() 的相应 4 行的信息。
这有效,但是,现在这里是我无法解决的问题:'loc_list' 中的每个位置都包含相同的 'a_location_list',包含来自所有 16 行的信息'Drop' 信息(以“1”、“2”等开头)而不仅仅是属于该位置的 4。
我不能把矛头指向这里的问题,所以有没有人可以帮助我解决这个问题?
我尽量简化了它。
好的,我继续搜索和阅读其他有类似问题的人,最后我自己找到了解决方案。
问题是我没有复制 'a_location_list'。
在classlocation()我修改了
def add_drop(self, drop):
self.a_location_list.append(copy.copy(drop))
到
def add_drop(self, drop):
self.a_location_list = self.a_location_list[:]
self.a_location_list.append(copy.copy(drop))
这使代码如我所愿。对于任何试图帮助我的人:无论如何谢谢!我希望通过在这里发布我自己的解决方案,其他人也能从中得到帮助。