简体   繁体   中英

More pythonic implementation for continuously looping through list

I have a list of tokens that I want to use for accessing an API. I'd like to always be able to select the next token in the list for use, and when the end of the list is reached, start over.

I have this now, which works, but I find it to be pretty messy and unreadable.

class tokenz:
    def __init__(self):
        self.tokens = ['a', 'b', 'c', 'd', 'e']
        self.num_tokens = len(tokens)
        self.last_token_used = 0

    def select_token(self):
        if self.last_token_used == 0:
            self.last_token_used += 1
            return self.tokens[0]
        elif self.last_token_used < (self.num_tokens - 1):
            self.last_token_used += 1
            return self.tokens[self.last_token_used - 1]
        elif self.last_token_used == (self.num_tokens -1):
            self.last_token_used = 0
            return self.tokens[self.num_tokens - 1]

Any thoughts on making this more pythonic?

Use itertools.cycle() to get a generator that repeats a list of items infinitely.

In [13]: tokens = ['a', 'b', 'c', 'd', 'e']

In [14]: import itertools

In [15]: infinite_tokens = itertools.cycle(tokens)

In [16]: [next(infinite_tokens) for _ in range(13)]
Out[16]: ['a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e', 'a', 'b', 'c']    

If you really want to make your posted code simpler, use modular arithmetic.

self.last_token_used = (self.last_token_used + 1) % len(self.tokens)

Also, you can use negative indexes in Python lists, so your if statements are unnecessary:

In [26]: for n in range(len(tokens)):
    ...:     print('{}: tokens[{}] = {}'.format(n, n-1, tokens[n-1]))
    ...:
0: tokens[-1] = e
1: tokens[0] = a
2: tokens[1] = b
3: tokens[2] = c
4: tokens[3] = d

And then your code becomes:

class tokenz:
    def __init__(self):
        self.tokens = ['a', 'b', 'c', 'd', 'e']
        self.num_tokens = len(self.tokens)
        self.last_token_used = 0

    def select_token(self):
        self.last_token_used = (self.last_token_used + 1) % self.num_tokens
        return self.tokens[self.last_token_used - 1]

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