if语句对不等式应用于分块列表的热烈使用

问题描述 投票:3回答:4

给出以下Python列表:

l1 = [0,1000,5000,10000,20000,30000,40000,50000] #8 values, 7 intervals
v1 = [1,2,3,4,5,6,7] #7 values
v2 = [a,b,c,d,e,f,g] #7 letters

我想检查数字是否包含在任何间隔中,并根据该间隔返回另一个值。

示例:

1. My test value is 1111
2. It belongs to the second interval: 1000 < 1111 < 5000
3. Hence I need to return b

我将通过以下方式解决这个问题:

  1. 创建l1的块
  2. 遍历每个块
  3. 为每个块编写一个if语句
  4. 返回对应于正确块的字母

我可以通过查看每对连续的数字来创建它的块:

def chunker(seq, size):
    return (seq[pos:pos + size] for pos in range(0, len(seq)))

for group in chunker(l1, 2):
   print(group)

此返回:

[0, 1000]
[1000, 5000]
[5000, 10000]
[10000, 20000]
[20000, 30000]
[30000, 40000]
[40000, 50000]
[50000]

我的问题:

  1. 是否有Python方式编写这些if语句,而不是每个块有一个?如果我有1,000个块怎么办?
  2. 如果存在,如何在不创建最后一个特定大小写的情况下处理最后一个块?
python list for-loop inequality
4个回答
2
投票

您可以zip列出l1l1[1:],它们将以您所需的方式进行间隔。对于一些额外的指针,由于可以对间隔进行排序,因此您可以将二进制搜索合并到其中,我将让您进行优化。该算法的当前运行时间为O(n)

from __future__ import print_function
l1 = [0,1000,5000,10000,20000,30000,40000,50000]
v2 = ['a','b','c','d','e','f','g']
element = 1111
interval = []
for left,right in zip(l1,l1[1:]):
    if left <= element <= right:
        interval = [left,right]
        break

print("answer is" ,interval)

输出

answer is [1000, 5000]

1
投票

仅适用于len 2的块。

l1 = [0,1000,5000,10000,20000,30000,40000,50000] #8 values, 7 intervals
# v1 = [1,2,3,4,5,6,7] #7 values
# v2 = [a,b,c,d,e,f,g] #7 letters

def chunker(seq, size):
    return (seq[pos:pos + size] for pos in range(0, len(seq)))


def chunk_with_value(list_of_chunks, value):
    """returns the chunk if the value is inside the range"""
    for chunk in list_of_chunks:
        if chunk[0] < value < chunk[1]:
            return chunk

chunks = chunker(l1, 2)

print(chunk_with_value(chunks, 1111))
# [1000, 5000]

1
投票

直接从itertools食谱书中:

def get_thing(value):

    def pairwise(iterable):
        from itertools import tee
        a, b = tee(iterable)
        next(b, None)
        return zip(a, b)

    interval_ranges = [
        0,
        100,
        500,
        1000
    ]

    # There are four interval ranges, so three intervals.
    things = [
        "A", # 0-100
        "B", # 100-500
        "C" # 500-1000
    ]

    for (begin, end), thing in zip(pairwise(interval_ranges), things):
        if begin <= value < end: # modify this to suit your needs. Is the range inclusive/exclusive?
            return thing
    return None


def main():

    thing = get_thing(400)
    print(thing)

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

输出:

B

0
投票

我相信您需要获取相应的间隔索引,并使用该索引来查询v2。这应该做到:

l1 = [0,1000,5000,10000,20000,30000,40000,50000] #8 values, 7 intervals
v2 = ['a','b','c','d','e','f','g'] #7 letters


def intervals(l):
    for i in range(len(l)-1):
        yield i, l[i:i+2]


def interval_value(val, interval_list, value_list):
    for i, interval in intervals(interval_list):
        if interval[0] <= val <= interval[1]:
            return value_list[i]


print(interval_value(1111, l1, v2))
print(interval_value(0, l1, v2))
print(interval_value(51000, l1, v2))
print(interval_value(40000, l1, v2))

输出:

b
a
None
f

您不需要v1值-您可以直接使用v2上的索引


0
投票

尽管其他答案很有用,但几乎所有答案都发现从v2输出的间隔不是期望的>

l1 = [0,1000,5000,10000,20000,30000,40000,50000]
v2 = ['a','b','c','d','e','f','g']
element = 1111
def get_interval(l1):
    for index, left,right in zip(range(len(l1)), l1, l1[1:]):
        if left <= element <= right:
            return v2[index]

>>> print("answer is:" ,get_interval(element))
>>> answer is: b
© www.soinside.com 2019 - 2024. All rights reserved.