В чем разница между random.sample и random.shuffle в Python

У меня есть список a_tot с 1500 элементами, и я хотел бы разделить этот список на два списка случайным образом. Список a_1 будет иметь 1300, а список a_2 будет иметь 200 элементов. Мой вопрос о том, как лучше рандомизировать исходный список из 1500 элементов. Когда я рандомизировал список, я мог взять один срез с 1300, а другой с 200. Одним из способов является использование random.shuffle, другим способом является использование random.sample. Есть ли различия в качестве рандомизации между двумя методами? Данные в списке 1 должны быть случайной выборкой, а также данные в списке 2. Любые рекомендации? используя shuffle:

random.shuffle(a_tot)    #get a randomized list
a_1 = a_tot[0:1300]     #pick the first 1300
a_2 = a_tot[1300:]      #pick the last 200

используя образец

new_t = random.sample(a_tot,len(a_tot))    #get a randomized list
a_1 = new_t[0:1300]     #pick the first 1300
a_2 = new_t[1300:]      #pick the last 200

Ответы на вопрос(6)

def shuffle(self, x, random=None, int=int):
    """x, random=random.random -> shuffle list x in place; return None.

    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.
    """

    if random is None:
        random = self.random
    for i in reversed(xrange(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

Источник для образца:

def sample(self, population, k):
    """Chooses k unique random elements from a population sequence.

    Returns a new list containing elements from the population while
    leaving the original population unchanged.  The resulting list is
    in selection order so that all sub-slices will also be valid random
    samples.  This allows raffle winners (the sample) to be partitioned
    into grand prize and second place winners (the subslices).

    Members of the population need not be hashable or unique.  If the
    population contains repeats, then each occurrence is a possible
    selection in the sample.

    To choose a sample in a range of integers, use xrange as an argument.
    This is especially fast and space efficient for sampling from a
    large population:   sample(xrange(10000000), 60)
    """

    # XXX Although the documentation says `population` is "a sequence",
    # XXX attempts are made to cater to any iterable with a __len__
    # XXX method.  This has had mixed success.  Examples from both
    # XXX sides:  sets work fine, and should become officially supported;
    # XXX dicts are much harder, and have failed in various subtle
    # XXX ways across attempts.  Support for mapping types should probably
    # XXX be dropped (and users should pass mapping.keys() or .values()
    # XXX explicitly).

    # Sampling without replacement entails tracking either potential
    # selections (the pool) in a list or previous selections in a set.

    # When the number of selections is small compared to the
    # population, then tracking selections is efficient, requiring
    # only a small set and an occasional reselection.  For
    # a larger number of selections, the pool tracking method is
    # preferred since the list takes less space than the
    # set and it doesn't suffer from frequent reselections.

    n = len(population)
    if not 0 <= k <= n:
        raise ValueError, "sample larger than population"
    random = self.random
    _int = int
    result = [None] * k
    setsize = 21        # size of a small set minus size of an empty list
    if k > 5:
        setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
    if n <= setsize or hasattr(population, "keys"):
        # An n-length list is smaller than a k-length set, or this is a
        # mapping type so the other algorithm wouldn't work.
        pool = list(population)
        for i in xrange(k):         # invariant:  non-selected at [0,n-i)
            j = _int(random() * (n-i))
            result[i] = pool[j]
            pool[j] = pool[n-i-1]   # move non-selected item into vacancy
    else:
        try:
            selected = set()
            selected_add = selected.add
            for i in xrange(k):
                j = _int(random() * n)
                while j in selected:
                    j = _int(random() * n)
                selected_add(j)
                result[i] = population[j]
        except (TypeError, KeyError):   # handle (at least) sets
            if isinstance(population, list):
                raise
            return self.sample(tuple(population), k)
    return result

Как вы можете видеть, в обоих случаях рандомизация по существу выполняется линиейint(random() * n), Таким образом, основной алгоритм по сути тот же.

 09 окт. 2012 г., 13:32
Обратите внимание на комментарии. Если у вас есть список, в котором вы можете использовать тасование (в зависимости от размера), он может быть более эффективным, поскольку вам не нужно проверять, чтобы убедиться, что вы уже выбрали определенный элемент.
from random import shuffle
from random import sample 
x = [[i] for i in range(10)]
shuffle(x)
sample(x,10)

list sample provide the no of argument in pic facility but shuffle provide the list of same length of input

random.shuffle() перетасовывает данноеlist на месте. Его длина остается неизменной.

random.sample() киркиn элементы из заданной последовательности без замены (которая также может быть кортежем или чем-то еще, если она имеет__len__()) и возвращает их в случайном порядке.

что они совершенно одинаковы, за исключением того, что один обновил первоначальный список, один использовал его (только для чтения). Нет различий в качестве.

shuffle() а такжеsample():

1) Shuffle изменит данные на месте, поэтому их ввод должен быть изменяемой последовательностью. Напротив, sample создает новый список, и его входные данные могут быть гораздо более разнообразными (кортеж, строка, xrange, bytearray, set и т. Д.).

2) Сэмпл позволяет вам выполнять меньше работы (т. Е. Частичное перемешивание).

Интересно показать концептуальные отношения между ними, продемонстрировав, что было бы возможно реализоватьshuffle() с точки зренияsample():

def shuffle(p):
   p[:] = sample(p, len(p))

Или наоборот, внедряяsample() с точки зренияshuffle():

def sample(p, k):
   p = list(p)
   shuffle(p)
   return p[:k]

Ни один из них не так эффективен в реальной реализации shuffle () и sample (), но он показывает их концептуальные отношения.

азал, пойти сshuffleпотому что читателю сразу становится понятнее, что он делает.

Ваш ответ на вопрос