Python 迭代嵌套列表中的值
我正在研究科学数据,并使用一个名为pysam的模块来获取文件中每个唯一“对象”的参考位置 最后,我得到了一个类似这样的“列表列表列表”(这里我提供了一个文件中只有两个对象的示例): 而且,对于Python 迭代嵌套列表中的值,python,list,Python,List,我正在研究科学数据,并使用一个名为pysam的模块来获取文件中每个唯一“对象”的参考位置 最后,我得到了一个类似这样的“列表列表列表”(这里我提供了一个文件中只有两个对象的示例): 而且,对于pos中的每个列表,我希望迭代这些值,并将value[I]与value[I+1]进行比较。当差值大于2(例如)时,我希望将这两个值(value[I]和value[I+1])存储到一个新列表中 如果我们称之为final\u pos,那么我想获得: final_pos = [[3,6,8,15,17,20],[
pos
中的每个列表,我希望迭代这些值,并将value[I]
与value[I+1]
进行比较。当差值大于2(例如)时,我希望将这两个值(value[I]
和value[I+1]
)存储到一个新列表中
如果我们称之为final\u pos
,那么我想获得:
final_pos = [[3,6,8,15,17,20],[1,5,8,20]]
一开始,这似乎很容易做到,但我肯定缺乏一些关于列表如何工作的基本知识,我无法迭代每个列表的每个值,然后将连续的值一起进行比较。。
如果有人有想法,我非常愿意听到
提前感谢您的时间
编辑:以下是我尝试的:
pos = [[1,2,3,6,7,8,15,16,17,20],[1,5,6,7,8,20]]
final_pos = []
for list in pos:
for value in list:
for i in range(len(list)-1):
if value[i+1]-value[i] > 2:
final_pos.append(value[i])
final_pos.append(value[i+1])
您可以在pos中迭代每个单独的列表,然后比较连续的值。当需要插入值时,可以使用临时集,因为不希望在最终列表中插入同一元素两次。然后,您可以将临时集转换为列表,并将其附加到最终列表中(排序后,以保持顺序)。此外,只有原始列表中的元素实际已排序时,排序才会起作用
pos = [[1,2,3,6,7,8,15,16,17,20],[1,5,6,7,8,20]]
final_pos = []
for l in pos:
temp_set = set()
for i in range(len(l)-1):
if l[i+1] - l[i] > 2:
temp_set.add(l[i])
temp_set.add(l[i+1])
final_pos.append(sorted(list(temp_set)))
print(final_pos)
输出
[[3, 6, 8, 15, 17, 20], [1, 5, 8, 20]]
编辑:关于您尝试的内容:
for list in pos:
这一行将为我们提供list=[1,2,3,6,7,8,15,16,17,20]
(在第一次迭代中)
这一行将为我们提供值=1
(在第一次迭代中)
现在,value
只是一个数字而不是一个列表,因此,value[i]
和value[i+1]
没有意义。您的代码有一个明显的“太多循环”问题。它还将结果存储为一个平面列表,您需要一个列表列表
它还有一个更微妙的缺陷:如果一行中有两个间隔匹配,那么可以多次添加相同的索引。为了避免这种情况,我在集合中注册了添加的索引
该错误不会显示在您的原始数据中(这让包括我在内的许多有经验的用户感到困惑),因此我对其进行了更改:
pos = [[1,2,3,6,7,8,11,15,16,17,20],[1,5,6,7,8,20]]
final_pos = []
for value in pos:
sublist = []
added_indexes = set()
for i in range(len(value)-1):
if value[i+1]-value[i] > 2:
if not i in added_indexes:
sublist.append(value[i])
## added_indexes.add(i) # we don't need to add it, we won't go back
# no need to test for i+1, it's new
sublist.append(value[i+1])
# registering it for later
added_indexes.add(i+1)
final_pos.append(sublist)
print(final_pos)
结果:
[[3, 6, 8, 11, 15, 17, 20], [1, 5, 8, 20]]
将索引存储在集中,而不是在对象不可散列(如自定义对象之间实现了自定义距离)或只有部分排序(waves)时(例如:pos=[[1,2,3,6,15,16,17,20,1,6,10,11],[1,5,6,7,8,20,1,5,6,7,8,20]
)如果您有一些非工作代码,我们很乐意帮助您修复。可以使用嵌套列表理解来完成此操作,但使用“传统”将使代码更具可读性用于循环。你熟悉zip
函数吗?我添加了一个我尝试过的例子,但老实说,我尝试了太多不同的东西,以至于我开始混合所有东西!我正在尝试自学python,所以可能到处都有一些新手错误。要回答你的问题@PM2Ring,我对zip函数,no.1.嵌套列表中是否有重复的元素?2.列表中的元素是否总是按顺序排列(升序或降序)?我已尝试修复您的代码,但是的,这种方法可以多次添加元素。这不会显示在您的输入数据中,但会显示在pos=[[1,2,3,6,7,8,11,15,16,17,20],[1,5,6,7,8,20]
如果我理解正确,为了避免在子列表中实现两次相同的值[i],您可以创建一个名为added_indexes的列表,每次向子列表添加值[i]时,您都会在其中添加i。并且每次要添加值[i]时,您都会选中added_indexes为了确保我还没有在那里。但是,为什么不直接检查子列表中的值[i]呢?是的,但这对于大列表来说要慢得多(集合查找更快)。此外,这是一个通用的解决方案,可以处理彼此之间有距离的对象列表。它可以处理部分排序的列表。我觉得这很奇怪,但如果速度更快,我一点也不抱怨!感谢您的时间,非常感谢:)尝试解决这个问题是一件很高兴的事。一开始看起来很琐碎,是的,但事实并非如此t、 如果列表真的很大,速度会更快。否则差异就不明显了。
pos = [[1,2,3,6,7,8,11,15,16,17,20],[1,5,6,7,8,20]]
final_pos = []
for value in pos:
sublist = []
added_indexes = set()
for i in range(len(value)-1):
if value[i+1]-value[i] > 2:
if not i in added_indexes:
sublist.append(value[i])
## added_indexes.add(i) # we don't need to add it, we won't go back
# no need to test for i+1, it's new
sublist.append(value[i+1])
# registering it for later
added_indexes.add(i+1)
final_pos.append(sublist)
print(final_pos)
[[3, 6, 8, 11, 15, 17, 20], [1, 5, 8, 20]]