Python - 如何从随机点开始循环遍历范围

时间:2012-03-15 17:06:30

标签: python list loops

我有一个类别列表(1-4),我想要一个循环迭代所有这些。但是,如果我的起点位于列表[0]之前,我需要能够以随机类别开始并环绕列表的开头。

我能够以相当冗长的方式做到这一点,但我想知道是否有更快/更优雅的方式。这就是我所做的(并且有效):

def categorize(self, cat):

    cats = [1,2,3,4]
    if cat > 1: 
        ncats = cats[:(cat-1)]
        cats = cats[(cat-1):]
        cats.extend(ncats)

    for c in cats:
        pass

10 个答案:

答案 0 :(得分:7)

from random import randrange
cats = [1,2,3,4]
i = randrange(len(cats))

for c in cats[i:]+cats[:i]:
   pass

(根据建议将choice更改为randrange

答案 1 :(得分:3)

好吧,你可以将它降低到cats = cats[cat - 1:] + cats[:cat - 1]

或者构建一个覆盖它的自定义数据结构,这样它就可以在列表中循环一次而且只能从任意点循环一次。

答案 2 :(得分:2)

一般的想法是:

>>> cats = [1, 2, 3, 4]
>>> import random
>>> r = random.randrange(len(cats))
>>> for i in range(len(cats)):
...     current = cats[(r+i)%len(cats)]
...     print current
...
3
4
1
2

答案 3 :(得分:1)

原始列表是否需要按顺序排列?因为否则你可以使用random.shuffle将其随机化:

cats = [1,2,3,4]
import random
random.shuffle(cats)
# Cats will now be in random order and can be looped normally.

答案 4 :(得分:1)

对于通用的warp / round-robin解决方案,我建议如下:

from itertools import cycle:
from random import choice

cats = [1,2,3,4]
def warp(iterable, start):
    c = cycle(iterable)
    while c.next() is not start: pass
    for counter in range(len(iterable)):
        yield c.next()

#random start part:
for cat in warp(cats, choice(cats)):
    print cat

可迭代项的类型无关紧要,您不必检查索引号,只需使用该项本身!

答案 5 :(得分:0)

from random import shuffle
shuffle(cats)
for c in cats:
    loop expressions here

答案 6 :(得分:0)

>>> cats = [1,2,3,4]
>>> import random
>>> random.shuffle(cats)
>>> cats
[1, 3, 4, 2]
>>> random.shuffle(cats)
>>> cats
[1, 4, 3, 2]

[更新]

>>> def circle_iter(items, start=0):
...     l = len(items)
...     for i in items:
...         yield items[start]
...         start += 1
...         if start == l: start = 0
...
>>> cats = [ 1, 2, 3, 4 ]
>>> for cat in circle_iter(cats, 2): print cat
...
3
4
1
2
>>> for cat in circle_iter(cats, 1): print cat
...
2
3
4
1

答案 7 :(得分:0)

使用模运算符!

import random

cats = [1,2,3,4]

i = random.randint(0,3)

for n in range(len(cats)):
    print cats[i%len(cats)]
    i+=1

答案 8 :(得分:0)

这应该这样做:

import random
cats = [1,2,3,4]
start = random.choice(cats)
new_order_cats = cats[cats.index(start):] + cats[:cats.index(start)]
print 'new order', new_order_cats

答案 9 :(得分:0)

import random
cats = [1,2,3,4]

def cycle_cats(items, start):
    sorted_items = items[items[start]:] + items[:items[start]]
    for item in sorted_items:
        yield item

for cat in cycle_cats(cats, random.choice(cats)):
    print cat

保留订单,不关心猫列表的长度,并期望调用者指定入口点。