如何根据过滤条件从Python列表中提取元素

0 投票
2 回答
858 浏览
提问于 2025-04-18 09:35

我有这样一个列表:

data = [[0.0322249406353, 1.00005691884],
[0.0322267803497, 0.999999986608],
[0.0322286200641, 0.499997756763],
[0.0322304597785, 0.333330346815],
[0.0322322994929, 0.249996641841],
[0.0322341392073, 0.199996418857],
[0.0322359789217, 0.166662936867],
[0.0322378186361, 0.142853306874],
[0.0322396583505, 0.12499608438],
[0.032241498065, 0.111107133551],
[0.0322433377794, 0.0999959728877],
[0.0322451774938, 0.0909050232541],
[0.0322470172082, 0.0833292318929],
[0.0322488569226, 0.0769189468948],
[0.032250696637, 0.0714244168966],
[0.032350696637, 0.],
[0.032450696637, -0.04]]

因为我之后会用到这个列表,而且我不想要一个在某个特定范围内信息很多,而在其他地方信息稀少的列表,所以我想过滤掉原来的列表。我的目标是得到一个新列表,这个新列表中,第二列的连续值之间的距离要大于一个给定的值,比如说 0.05,前提是这些值在 [0,1] 的范围内。

这个列表的数据是这样的:第二列的值是不断减少的,所以 data[i][1] < data[i-1][1]

我想要的列表大概是这样的:

data2 = [[0.0322249406353, 1.00005691884],
[0.0322267803497, 0.999999986608],
[0.0322286200641, 0.499997756763],
[0.0322304597785, 0.333330346815],
[0.0322322994929, 0.249996641841],
[0.0322378186361, 0.142853306874],
[0.032350696637, 0.],
[0.032450696637, -0.04]]

有没有什么办法可以做到这一点?谢谢!

编辑(第一次尝试):

data2=[] 
for i in xrange(0,len(data)): 
    if 0>data[i][1] or data[i][1]>1:
        data2.append([data[i][0],data[i][1]])
    for j in xrange(0,len(data)):
        if j>i and 0<data[i][1]<1 and 0<data[j][1]<1:
            if data[i][1] - data[j][1] > 0.05:
                data2.append([data[i][0],data[i][1]])
                i = j
                break

这个方法部分有效,因为我得到的新列表不完整而且不正确:

data2=[[0.0322267803497, 0.999999986608], [0.0322286200641, 0.499997756763], [0.0322304597785, 0.333330346815], [0.0322322994929, 0.249996641841], [0.0322341392073, 0.199996418857], [0.0322359789217, 0.166662936867], [0.0322378186361, 0.142853306874], [0.0322396583505, 0.12499608438], [0.032450696637, -0.04]]

2 个回答

0

你应该使用生成器来过滤你的列表。下面是一个例子,展示如何只获取第一个数字是偶数的列表:

l = [ [0,1], [1,2], [2,3], [3,4] ]
def get_first_divisible_by_2(l):
    for i,j in l:
        if not i % 2:
            yield i,j
[ c for c in get_first_divisible_by_2(l) ]
[(0, 1), (2, 4)]

或者你可以使用生成器推导式:

list( ( (i,j) for i,j in l if not i % 2 ) )
[(0, 1), (2, 4)]

只需根据你的过滤条件进行调整,可能还可以结合协程,这样你就能轻松处理之前的结果了。

1

这里有几个小建议:

  • 看起来你想要逐个检查数据结构中的每个元素,看看它们是否符合某个条件。那么,什么样的循环可以帮你做到这一点呢?
  • 对于每个元素,你想要把它和前一个元素进行比较,检查这两个元素之间的差值是否大于某个特定的值。那么,你的条件应该是什么样的呢?
  • 最后,如果你的条件成立,你想对这个元素做什么呢?

补充:

使用for循环是个不错的选择,不过这里不需要嵌套循环。你可以简单地把任何大于1或小于0的值添加到新列表中。对于其他元素,你只需要检查新生成的列表中最后一个元素和当前要检查的元素之间的差值是否在规定范围内,然后决定是添加还是忽略它。

补充 2:

这里有一个可能的解决方案:

data2=[]
limit=0.1
j = 0
# get all values > 1 in the result list
while data[j][1] > 1:
    data2.append(data[j])
    j = j + 1
# the next one too
data2.append(data[j])
for i in xrange(0,len(data)): 
# compare current to last in results and see if it is smaller than the limit
    if abs(data[i][1] - data2[len(data2)-1][1]) > limit and data[i][1] > 0:
        data2.append(data[i])
        j = i
# in the end add all the elements < 0
for i in xrange(0,len(data)):
    if data[i][1] < 0:
        data2.append(data[i])

撰写回答