Питоны самый быстрый способ рандомизации случая строки - PullRequest
6 голосов
/ 01 декабря 2011

Я хочу рандомизировать случай строки, вот что у меня есть:

word="This is a MixeD cAse stRing"
word_cap=''
for x in word:
        if random.randint(0,1):
                word_cap += x.upper()
        else:
                word_cap += x.lower()
        word = word_cap

print word

Мне интересно, не могли бы вы использовать списки, чтобы сделать это быстрее. Я не могу использовать функции lower () и upper () в случайном выборе я пытался сделать что-то вроде

''.join(randomchoice(x.upper(),x.lower()) for x in word)

но я думаю, что это неправильно. что-то подобное, хотя возможно?

Ответы [ 2 ]

8 голосов
/ 01 декабря 2011
import random
s = 'this is a lower case string'

''.join(random.choice((str.upper,str.lower))(x) for x in s)

random.choice случайным образом выбирает одну из двух функций str.upper, str.lower.

Затем эта функция применяется к x для каждой буквы во входной строке s.

Если исходная строка содержит все буквы в нижнем регистре, я бы использовал этот код:

''.join(x.upper() if random.randint(0,1) else x for x in s)

потому что исходный код будет использовать избыточный str.lowercase на половине букв в случае строчной начальной буквы.

Кстати, посмотрите на другой ответ Майкла Дж. Барбера. У Python большие расходы за вызовы функций. В своем коде он называет str.upper только один раз. В моем коде str.upper вызывается примерно для половины символов исходной строки. Таким образом, временная строка в верхнем регистре создается в памяти, временная эффективность его кода может быть намного выше.


О чудо:

Сравнение временных кодов: https://ideone.com/eLygn

4 голосов
/ 01 декабря 2011

Попробуйте это:

word="this is a lower case string"
caps = word.upper()
''.join(x[random.randint(0,1)] for x in zip(word, caps))

Это должно превзойти вашу версию, потому что она делает намного меньше вызовов на upper и потому, что, что более важно, избегает O (N ^ 2) последовательных добавлений, которые вы использовали вверсия с петлями.

С изменением вопроса вам нужно будет создать как строчные, так и прописные версии:

word="This is a MixeD cAse stRing"
caps = word.upper()
lowers = word.lower()
''.join(random.choice(x) for x in zip(caps, lowers))

Как подсказал Тим Пицкер в комментариях, я использовал random.choice чтобы выбрать буквы из кортежей, созданных с помощью вызова zip.

Поскольку вопрос был изменен, чтобы больше сосредоточиться на скорости, наиболее быстрый подход, вероятно, будет использовать Numpy:

''.join(numpy.where(numpy.random.randint(2, size=len(caps)), list(caps), list(lowers)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...