Rotate (like "clockwise") a singe entry of a tuple in a list of tuples as a Focus

Viewed 76

I have to rotate (like "clockwise") a singe entry of a tuple in a list of tuples. I use this single tuple as a focus. And when the flag was placed on the end of the list of tuples, it next should be again on the begin.

x = []
x.append(('search','https://www.search.com','1'))   # '1' is the focus
x.append(('financials','https://www.stock-exchange.com','0'))
x.append(('fastfood','https://www.burgers.com','0'))
x.append(('tv','https://www.tv.com','0'))

print x

[('search','https://www.search.com','1'),('financials','https://www.stock-exchange.com','0'),('fastfood','https://www.burgers.com','0'),('tv','https://www.tv.com','0')]

What I need to have, is this (abstract displayed)...

 - - *
 - - 
 - - 
 - -

Then I must switch the focus to the "next line"...

 - - 
 - - *
 - - 
 - -

...and later...

- - 
- - 
- - *
- -

...then...

 - - 
 - - 
 - - 
 - - *

...and then this again...

 - - *
 - - 
 - - 
 - -

...and so on.

Sometimes I need to find the focus in my code and extract the data from the first and second entry where the focus (third entry) is currently placed. With this "one-liner", I can find the focus, and can store all entries to a, b and c:

a,b,c =  list(data[[index for (index, a_tuple) in enumerate(x) if a_tuple[2]=='1'][0]])

I like those "one-liners". But changing the focus to the "next line" seems to be not so easy.

newX = []                           # Create a new List for x
if '1' in x[len(x)-1][2]:           # Determine whether the focus is currently placed on the end, and if Yes, place it to the begin
    for b in range(0,len(x),1):     # Parse
        if b == 0:                  # Set the focus on the begin
            newX.append((x[b][0],x[b][1],'1'))  # Set new focus to new list
        else:                       # No focus for all other entries
            newX.append((x[b][0],x[b][1],"0"))  # Set "no-focus" to all other entries in new list
else:                               # The focus was not on the end.  Where is it?
    a = 0                           # A little helper
    for b in range(0,len(x),1):     # Parse again
        if '1' in x[b][2]:          # Focus found
            a = b                   # Set the current tuple-number to a
            break                   # Already found... don't go on with for/next
    for b in range(0,len(x),1):     # Parse again
        if b == a+1:                # Set the new focus on next entry as it was before
            newX.append((x[b][0],x[b][1],'1'))  # Set new focus to new list
        else:                       # No Focus for all other entries
            newX.append((x[b][0],x[b][1],"0"))  # Set "no-focus" to all other entries in new list
x = newX                            # Set x with the new list
del newX,a,b                        # Save some memory

I managed to do this, but I don't like my code. This task looks so simple that I think there also has to be a "one-liner" for it, something that is embedded internally in Python and that is exactly intended for this. I have v2.7. Anyone an idea?

2 Answers

If I understand you correctly, you want simple modulo (%) operator.

Remove the third item from the tuple, make new variable named selected that will hold the value of selected item:

lst = [
    ("search", "https://www.search.com"),
    ("financials", "https://www.stock-exchange.com"),
    ("fastfood", "https://www.burgers.com"),
    ("tv", "https://www.tv.com"),
]
selected = 0

def next_selected(lst, cur_selected):
    return (cur_selected + 1) % len(lst)

selected = next_selected(lst, selected)  # will wrap around

Then getting the selected item is simply:

a, b = lst[selected]

I think I've got it

    lst = {
        0: ("0","search", "https://www.search.com"),
        1: ("0", "financials", "https://www.stock-exchange.com"),
        2: ("*", "fastfood", "https://www.burgers.com"),
        3: ("0", "tv", "https://www.tv.com"),
    }
    
    def next_selected(lst, cur_selected):
        return (cur_selected + 1) % len(lst)
    
    for index, key in enumerate(lst):               # parse
        if lst[index][0] == "*":                    # found focus
            break
    
    lst[index] = "0",lst[index][1],lst[index][2]    # delete old focus
    
    selected = index                                # use index from above parsing
    selected = next_selected(lst, selected)         # will wrap around
    
    lst[selected] = '*',lst[selected][1],lst[selected][2]   # store focus to selected
    
    a,b = lst[selected][1],lst[selected][2]         # get values of selected
Related