Python在一个列表中查找属于另一个列表值的值的方法

时间:2018-03-11 00:12:09

标签: python python-2.7

使用一些研究数据并尝试找到一种好的Pythonic方法来确定一个列表中的值是否落在另一个列表的值之间。每个数据文件的每一行都包含一个连续的年份列表,表示在左侧找到一个重要值的年份,另一个年份的顺序列表表示在右侧找到一个绑定值的年份,由一个每年之间的管道特征和空间。

示例:1950 1955 1960 1977|1957 1958 1959 1966 1970 1975 1980 2015

因此,在上面的例子中,1950年没有平局,但1955年与1957年,1958年和1959年并列。1960年与1966年和1970年并列。1977年与1980年和2015年并列。

这些列表是根据对更改数据的评估动态创建的,因此在处理此数据时,任何给定的迭代,管道字符左侧或右侧的列表可能包含更多或更少的项目。

处理这些列表时,左侧的年份值为1,但右侧的年份必须根据它们与左侧列表中的年份相关的频率分配加权值管道角色的一面。

分配给右边的平均年份的价值权重需要以互惠的方式递减。例如,1957年将被赋予0.5的加权值,1958年将被赋予0.33的加权值,而1959年将被赋予0.25的加权值。那么,下一个关联年份的范围将大于1960年并且不到1977年,并且从1966年开始,然后再次以加权值0.5开始。

查看Stack Overflow并发现类似于我想要做的事情,但没有"介于()" Python中的函数:

Finding values in one vector that are between the values in another vector

是否有Pythonic方法进行这样的比较,并根据它们在左边的重要年份之间如何使用Python 2.7.5并且没有额外的添加 - 动态地为右边的关联年份赋值。在图书馆?

1 个答案:

答案 0 :(得分:1)

我相信你的问题可以分解为两个步骤:

  • 计算左侧每年的范围。
  • 计算右侧每年的权重。

Python的range内置和列表/字典理解应该足够了。

以下是一个示例实现。我已经包含了中间输出,以帮助您了解每个阶段发生的事情。

from itertools import zip_longest

mystr = '1950 1955 1960 1977|1957 1958 1959 1966 1970 1975 1980 2015'

lsts = [list(map(int, x.split())) for x in mystr.split('|')]

# [[1950, 1955, 1960, 1977], [1957, 1958, 1959, 1966, 1970, 1975, 1980, 2015]]

def ranger(x1, x2, lst):
    return [i for i in lst if i in range(x1, x2)]

d = {i: ranger(i, j, lsts[1]) for i, j in \
     zip_longest(lsts[0], lsts[0][1:], fillvalue=lsts[1][-1]+1)}

# {1950: [], 1955: [1957, 1958, 1959], 1960: [1966, 1970, 1975], 1977: [1980, 2015]}

w = {k: [1/(i+2) for i in range(len(v))] if v else [] for k, v in d.items()}

# {1950: [],
#  1955: [0.5, 0.3333333333333333, 0.25],
#  1960: [0.5, 0.3333333333333333, 0.25],
#  1977: [0.5, 0.3333333333333333]}