简体   繁体   中英

efficient comparison of values in a python list

I have a list made out of tuples such as the one below:

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

having a sett of different values for the level key in the dictionary(increasing, but not always integers ie 1, 2, 3, 3B, 4A, 5, 5A, 6, 7), the id increasing incrementally and consists only of integers.

what I'm trying to find out is the value of the first two values in the first element of the tuple ie the floating points 2809.399... and 1032.5989... in the case of the level being +/- 1 different from the ones I'm currently at. In other words, level 2 id 1 should be looking for id 1 on levels 1 and 3.

What I've come up with for this is the following:

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])

and it works. However it requires me to define long if statements for each of the case. Is there a more efficient way (algorithm) of abstracting this without having to create 7 if loops (one for each level)?

Two notes:

  1. You don't write for i in range(len(xs)): # use xs[i] in Python, as much as you don't write int i = 0; while (i < N) { /* use xs[i]; */ i++; } int i = 0; while (i < N) { /* use xs[i]; */ i++; } int i = 0; while (i < N) { /* use xs[i]; */ i++; } in C. You write for x in xs: # use x .
  2. Consider using a named tuple for descriptive names for the values. Also consider restructuring the data. For instance, you could put use a format like { level_1: { id_1: (val_1, val_2), id_2: ...}, level_2: ...} .

As for the actual problem: You can generalize it even with the current format (note that the code assumes the levels are integers - I know they aren't, but I don't know how you get from one level to the next one in your system either).

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

Would be easier (and faster, complexity-wise - it's currently O(n**2) ) with more thought-out data structures.

You should restructure your data. The format it is currently in is not conducive to the problem you are trying to solve, because it is in sequential form and you are effectively trying to do random access as in a dictionary.

Rearrange it into a dictionary:

'level':
    'id':
        (data)

There is another problem in that you need to define what it means to be "+/- 1 from the level you are currently at" if your levels are not integers. That is, what is one level up from 3 say? 3B , 4A , 4B , ...? To solve that you will probably want to redefine your levels to be integers and store a mapping from string name to integer value. Integers are a good datatype for storing levels in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM