LINUX.ORG.RU

[python]Генератор снега

 


0

3

Привет, у нас первый снег:

   *        .                 .              .                      * 
                                                                      
       .                            *                                 
         .*                                      *  .     *           
             .                                                        
                 *                                   .   .            
                      *       .               *      *                
          *                                         *     *     .    .
                           *                         .                
      *                  .                                         .  
               .        .  *                 *                  *     
             .      .                    .                .           
         .                                   .                        
                 .               .                                    
  *       .                        .       .                        . 
           *                         .              *                 
                .                  *          *         *             
           .  .                        .               .  *.          
          *    *   **                                    *            

Можно ли красиво написать такой генератор рандомного снега в одну строчку, например list comprehension'ом?

import random

freq = 0.95
flakes = ['*', '.']

def snow(x, y):
    for _ in range(y):
        s = ''
        for _ in range(x):
            if random.random() > freq:
                s += random.choice(flakes)
            else:
                s += ' '
        print s

snow(70, 20)

Думал поначалу нагенерить снежинок, потом ljust и перемешать, но random.shuffle() меняет in-place, не возвращая модифицированной строки.

Алсо! В данном примере s при присваивании каждый раз указывает на новый объект, поскольку строки неуязвимы — как это сказывается на потреблении помяти? Сборщик какой-нибудь подчищает сразу же?


import random

freq = 0.95
flakes = ['*', '.']

def echo(x):
  print x

def snow(x, y):
  choose = lambda x: random.choice(flakes) if random.random() > freq else ' '

  print '\n'.join([''.join([random.choice(flakes) if random.random() > freq else ' ' for _ in range(x)]) for _ in range(y)])
  map(echo, [''.join([random.choice(flakes) if random.random() > freq else ' ' for _ in range(x)]) for _ in range(y)])
  print '\n'.join(map(lambda _: ''.join(map(choose, range(x))), range(y)))

snow(70, 20)

Не сказал бы, что красиво, но зато в одну строчку.

rival ★★
()

Сборщик какой-нибудь подчищает сразу же?

Должен собирать, ссылки на эту строку нигде не остается, вроде.

baverman ★★★
()
Ответ на: комментарий от rival

> print '\n'.join([".join([random.choice(flakes) if random.random() > freq else ' ' for _ in range(x)]) for _ in range(y)])

Действительно! Я так и думал сначала, но мой усталый мозг почему-то в упор не видел возможности else clause с пробелом.

xio
() автор топика

А вот с распределением:

import random

flakes = ' ' * 900 + '.' * 70 + '*' * 30

def snow(w, h):
    for _ in range(h):
        yield ''.join(random.choice(flakes) for r in range(w))

for s in snow(70, 20):
    print s
baverman ★★★
()
def snow(x, y):
    s = ''
    for _ in range(x*y):
        if random.random() > freq:
            s += random.choice(flakes)
    a = random.sample(s.ljust(x*y), x*y)
    for i in range(x, len(a), x+1):
        a[i:i] = '\n'
    print ''.join(a)
anonymous
()
Ответ на: комментарий от anonymous

> random.sample

Вот тогда, что хотел:

print '\n'.join([".join(random.sample(list(".join([random.choice(flakes) for _ in range(w) if random.random() > 0.95]).ljust(w)), w)) for _ in range(h)])

Но, конечно, с print '\n'.join([".join([random.choice(flakes) if random.random() > freq else ' ' for _ in range(x)]) for _ in range(y)]) не сравнить.

xio
() автор топика
Ответ на: комментарий от xio

> Изящно же! Еще пишет, «не сказал бы, что красиво».
Я, конечно, понимаю желание уместить всё в одну строчку, но все же код становится нечитабельным.

rival ★★
()

у меня вышло так:

def snow(x, y, freq=15, chars=('*', '.')):
    print ''.join([''.join([random.choice( [' '] * freq + list(chars)) for _ in xrange(x)])+'\n'  for _ in xrange(y)])

Zubchick
()
Ответ на: комментарий от Zubchick

или в более читаемом виде:

def snow2(x, y, freq=10, chars=('*', '.')):
    flakes = [' '] * freq + list(chars)
    for i in xrange(y):
        for j in xrange(x):
            print random.choice(flakes),
        print '\n'

выше тоже подчеркивания на i,j заменить надо... а то неверно работает

Zubchick
()
Ответ на: комментарий от anonymous

>range(0,80)
range(80) тогда уж, анон.

Ровно 80 символов.

Я насчитал 75. С моей правкой - 73.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.