2012-01-18 3 views
3

Это моя проблема: мне нужно создать случайную строку длиной 50 символов, состоящую из 1 и 0 s.Встроенный метод генерации случайных строк фиксированной длины из заданных символов

Я знаю, как решить эту проблему, и даже для нее есть однострочный. Я также искал различные решения этой проблемы на SO, только чтобы получить то, что я уже знаю (1, 2 и т. Д.). Но я действительно хочу самый Pythonic способ сделать это.

В настоящее время я склоняюсь к ''.join((random.choice([0,1]) for i in xrange(50)))

Есть ли более вещий способ сделать это? Есть ли встроенный модуль, который делает что-то вроде этого, возможно, в itertools?

+1

перфекционист? '' – wim

ответ

6

Для python2.7 или лучше: (. В python2.6, используйте '{0:050b}' вместо '{:050b}')

In [83]: import random 

In [84]: '{:050b}'.format(random.randrange(1<<50)) 
Out[84]: '10011110110110000011111000011100101111101001001011' 


Объяснение:

Метод string.format может преобразовывать целые числа в их двоичные представления строк. Основной код формата сделать это '{:b}':

In [91]: '{:b}'.format(10) 
Out[91]: '1010' 

Чтобы сделать строку шириной 50, используйте код формата '{:50b}':

In [92]: '{:50b}'.format(10) 
Out[92]: '            1010' 

и заполнить пробелы с нулями, используйте {:050b}:

In [93]: '{:050b}'.format(10) 
Out[93]: '00000000000000000000000000000000000000000000001010' 

syntax for str.format Сначала немного сложнее. Вот моя шпаргалка:

http://docs.python.org/library/string.html#format-string-syntax 
replacement_field ::= "{" field_name ["!" conversion] [":" format_spec] "}" 
field_name  ::= (identifier|integer)("."attribute_name|"["element_index"]")* 
attribute_name ::= identifier 
element_index  ::= integer 
conversion  ::= "r" | "s" 
format_spec  ::= [[fill]align][sign][#][0][width][,][.precision][type] 
fill    ::= <a character other than '}'> 
align    ::= "<" | ">" | "=" | "^" 
         "=" forces the padding to be placed after the sign (if any) 
          but before the digits. (for numeric types) 
         "<" left justification 
         ">" right justification 
         "^" center justification 
sign    ::= "+" | "-" | " " 
         "+" places a plus/minus sign for all numbers  
         "-" places a sign only for negative numbers 
         " " places a leading space for positive numbers 
#      for integers with type b,o,x, tells format to prefix 
         output with 0b, 0o, or 0x. 
0      enables zero-padding. equivalent to 0= fill align. 
width    ::= integer 
,      tells format to use a comma for a thousands separator 
precision   ::= integer 
type    ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | 
         "o" | "x" | "X" | "%" 
    c convert integer to corresponding unicode character 
    n uses a locale-aware separator 
    % multiplies number by 100, display in 'f' format, with percent sign 
+0

Я советую вам шляпу, сэр. –

+0

Не могли бы вы добавить объяснение? Например, что делает '' {: 050b} ''? Кроме того, у этого есть те же проблемы с обобщением, что и ответ Майка Самуэля. Но для меня это кажется более pythonic (не знаю почему) – inspectorG4dget

+1

@ inspectorG4dget, '{}' означает замену аргумента 'format' для последовательности; ':' означает принять аргумент по умолчанию (следующий) и применить следующий формат; '050' означает создание 50-значного результата с ведущими нулями; 'b' означает кодирование в двоичном формате. –

2
# Choose a number in [0, 1L << 50), and format it as binary. 
# The [2:] lops off the prefix "0b" 
bit_str = bin(random.randint(0, (1L << 50) - 1))[2:] 
# We then need to pad to 50 bits. 
fifty_random_bits = '%s%s' % ('0' * (50 - len(bit_str)), bit_str) 
+0

Вы можете использовать 'random.getrandbits (50)' вместо вашего вызова 'randint'. –

+0

(+1) Конечно, это работает для строки, состоящей из '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 's' Есть ли способ обобщить это? – inspectorG4dget

+1

Более короткий способ для прокладки: 'bit_str.rjust (50," 0 ")'. – MRAB

2

Это выглядит довольно pythonic для меня. Вы можете потерять скобки, если вы хотите сэкономить на персонажей:

''.join(random.choice(['0','1']) for i in xrange(50)) 
+1

'random.choice ('01')' тоже должен работать нормально. –

0
from random import choice 
from itertools import repeat 
# map or generator expression, take your pick 
"".join(map(choice, repeat("01", 50))) 
"".join(choice(x) for x in repeat("01", 50)) 

Измените входы repeat обобщать.

Смежные вопросы