【问题标题】:efficient comparison of values in a python listpython列表中值的有效比较
【发布时间】:2011-02-05 21:25:46
【问题描述】:

我有一个由元组组成的列表,如下所示:

(2809.3994479562093, 1032.5989696312365, 0.0), {'level': '2', 'id': '1'})

对于字典中的级别键有一组不同的值(增加,但不总是整数,即 1、2、3、3B、4A、5、5A、6、7),id 逐渐增加并且仅包含整数。

我要找出的是元组第一个元素中前两个值的值,即浮点 2809.399... 和 1032.5989... 在级别为 +/- 1 的情况下和我现在的不同。 也就是说,level 2 id 1 应该在level 1 和level 3 上寻找id 1。

我想出的是以下几点:

for x in xrange(len(net.lifts)):
    if net.lifts[x][1]["level"] == "2":
        for y in xrange(len(net.lifts)):
            if (net.lifts[y][1]["level"] == "1" or net.lifts[y][1]["level"] == "3") and net.lifts[y][1]["id"] == net.lifts[x][1]["id"]:
                print "edge:" + str(net.lifts[x][0][:2]) + str(net.lifts[y][0][:2])

它有效。但是,它需要我为每个案例定义长 if 语句。 有没有更有效的方法(算法)来抽象它而不必创建 7 个 if 循环(每个级别一个)?

【问题讨论】:

    标签: python algorithm logic


    【解决方案1】:

    两个音符:

    1. 你不用 Python 写 for i in range(len(xs)): # use xs[i],就像你不用 C 写 int i = 0; while (i < N) { /* use xs[i]; */ i++; } 一样。你写 for x in xs: # use x
    2. 考虑使用named tuple 作为值的描述性名称。还要考虑重组数据。例如,您可以使用{ level_1: { id_1: (val_1, val_2), id_2: ...}, level_2: ...} 之类的格式。

    至于实际问题:即使使用当前格式,您也可以对其进行概括(请注意,代码假定级别是整数 - 我知道它们不是,但我不知道您如何从一个级别到系统中的下一个)。

    for lift in net.lifts:
        for other_lift in net.lifts:
            if (lift[1]['id'] == other_lift[1]['id'] and
                abs(lift[1]['level'] - other_lift[1]['level']) <= 1):
                # got one
    

    使用经过深思熟虑的数据结构会更容易(并且更快、更复杂 - 目前是 O(n**2))。

    【讨论】:

    • 非常好的提示。谢谢。两层之差必须严格等于1且不小于1(也就是说电梯都在同一层)
    【解决方案2】:

    您应该重组您的数据。它当前的格式不利于您尝试解决的问题,因为它是顺序形式的,您实际上是在尝试像在字典中一样进行随机访问。

    重新排列成字典:

    'level':
        'id':
            (data)
    

    还有一个问题是,如果您的级别不是整数,您需要定义“与当前级别相差 +/- 1”的含义。也就是说,比3 高一级是什么? 3B, 4A, 4B, ...?为了解决这个问题,您可能需要将级别重新定义为整数并存储从字符串名称到整数值的映射。整数是存储关卡的好数据类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 2023-04-09
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多