How to select a chunk of list between two values in python

爱⌒轻易说出口 提交于 2021-02-11 08:14:33

问题


I have a list of values like this:

vect_i = ['a','X','c','g','X','t','o','X','q','w','e','r','t','y','u','i','o','p','Y','x','c','v','b','Y','b','n','m','Y','q','a','d','Y',]

my goal would be to select in a smart way only the values that are within the last X and the first Y (notice capital X and Y).

The output should be something like this:

vect_f = ['q','w','e','r','t','y','u','i','o','p','Y','x','c','v','b']

Is there a smart way to do this selection. I have figured out a way to do it by counting the number of Xs and Ys and collect only what is comprehended between the corresponding indexes but this is very bad coding in my opinion.

Could you suggest me a nice way to achieve my goal?


回答1:


One line:

vect_i[(vect_i.reverse(), len(vect_i) - vect_i.index('X'), vect_i.reverse())[1] : vect_i.index('Y')]

or

vect_i[len(vect_i) - vect_i[::-1].index('X') : vect_i.index('Y')]



回答2:


vect_i[len(vect_i)-vect_i[::-1].index('X'): vect_i.index('Y')]

retrurn the desired output




回答3:


Most of the other answers are either calling index multiple times, or mutating and/or copying the list in some form. I think you can simply use enumerate and get the slice indices for the desired positions in O(n):

ix = iy = 0
for i, v in enumerate(vect_i):
    if v == 'X':
        ix = i
    elif v == 'Y':
        iy = i
        break

print(vect_i[ix+1:iy])
# ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']



回答4:


that would be my way:

indexOfLastX = len(vect_i) - 1 - vect_i[::-1].index("X")
indexOfFirstY = vect_i.index("Y")
print(vect_i[indexOfLastX + 1:indexOfFirstY])

resulting in "['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']". In your example result is a "Y", what is suprising, when you want to stop at the first "Y"...




回答5:


Something like this?

def sliceBetween(arr, ch1, ch2):
    if ch1 not in arr or ch2 not in arr:
        return []
    left = len(arr) - arr[::-1].index(ch1) - 1
    right = arr.index(ch2)
    if left >= right:
        return []
    return [left+1:right]



回答6:


Just try with this code:

endIndex = vect1.index('Y')
dum = ''.join(vect1)
startIndex = dum.rfind('X')
print vect1[startIndex+1:endIndex]



回答7:


get all diffs between every X > Y, "last X and the first Y" are the first item in vect_f

vect_f = []
x = [x for x,o in enumerate(reversed(vect_i)) if o == "X"]
for diff in x:
    sub_vect_f = []
    for sub_diff in range(len(vect_i)- diff, len(vect_i)):
        val = vect_i[sub_diff]
        if val!="Y":
            sub_vect_f.append(val)
        else:
            vect_f.append(sub_vect_f)
            break

for vect in vect_f:
    print (vect)

['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']
['t', 'o', 'X', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']
['c', 'g', 'X', 't', 'o', 'X', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']



回答8:


Bisect search in temporary sorted list will be fast (O(2 log n)). But there is disadvantages - you need to create additional sorted list with original indexes. You can use it if selection need to be made more than once with different chars and original list is not very big:

from bisect import bisect_left

sorted_list_with_idx = sorted((v,i) for i,v in enumerate(vect_i))

# -1 because we need to insert before index of first 'Y' in list
sorted_y_idx = bisect_left(sorted_list_with_idx, ('Y', -1))

# len(vect_i) used as max index to insert to right of last 'X'
# -1 because last 'X' will be before inserted 'new X'
sorted_x_idx = bisect_left(sorted_list_with_idx, ('X', len(vect_i))) - 1

y_idx = sorted_list_with_idx[sorted_y_idx][1]
x_idx = sorted_list_with_idx[sorted_x_idx][1]

>>> sorted_list_with_idx
[('X', 1), ('X', 4), ('X', 7), ('Y', 18), ('Y', 23), ('Y', 27), ('Y', 31),
 ('a', 0), ('a', 29), ('b', 22), ('b', 24), ('c', 2), ('c', 20), ('d', 30), 
 ('e', 10), ('g', 3), ('i', 15), ('m', 26), ('n', 25), ('o', 6), ('o', 16), 
 ('p', 17), ('q', 8), ('q', 28), ('r', 11), ('t', 5), ('t', 12), ('u', 14), 
 ('v', 21), ('w', 9), ('x', 19), ('y', 13)]

>>> y_idx
18
>>> x_idx
7

>>> vect_i[x_idx+1:y_idx]
['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p']


来源:https://stackoverflow.com/questions/40630340/how-to-select-a-chunk-of-list-between-two-values-in-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!