KnowsCount
KnowsCount

Reputation: 327

how do you convert a for loop output into a list?

I've been through some answers to similar questions on stackoverflow, whereas I appears to be facing a quite delicate situation wherein some of them won't work. below is my code:

import random
from datetime import datetime
array = ['a', 'b', 'c', 'd', 'e', 'f']
def log():
    print(random.choice(array))

characters_to_remove = ".-:"
now = str(datetime.now()).replace(" ", "")
for character in characters_to_remove:
    now = now.replace(character, "")

# print(now)
time = now
time = int(time)
# print(time)

paramTime = time % 535
# print(paramTime)

# param = int(str(paramTime)[:2])
param = int(str(paramTime)[:1])
# print(param)

def repeat(times, func):
    for i in range(param): func()

print(repeat(param, log))
# print(str(repeat(param, log)).split(""))
# print('----------')

as you can see, the for loop is used in order to call a function (for multiple times):

def repeat(param, func):
    # param stands for the number of times the function is to be called
    for i in range(param): func()

now I want to convert my outputs as a list and ergo be able to get the most commonly outputted value... what do I do?

Upvotes: 0

Views: 495

Answers (4)

enzo
enzo

Reputation: 11496

If you can't change your log function (i.e. it belongs to a third-party library), you could change the value of sys.stdout using contextlib.redirect_stdout:

import io
import contextlib

with contextlib.redirect_stdout(io.StringIO()) as fake_stdout:
    # ...

Change # ... with your calculation and at the end access the outputted values using fake_stdout.getvalue():

import io
import contextlib

with contextlib.redirect_stdout(io.String()) as fake_stdout:
    import random
    
    def log():
        print(random.randint(1, 10))
        
    def repeat(param, func):
        for i in range(param): 
            func()

    repeat(10, log)

print(fake_stdout.getvalue())

The above outputs

6
9
10
10
4
9
10
8
5
3

To convert it to a list and manipulate it, just do

outputs = fake_stdout.getvalue().strip().split()
print(outputs)
# Outputs ['6', '9', '10', '10', '4', '9', '10', '8', '5', '3']

import collections
print(collections.Counter(outputs).most_common(1)[0][0])
# Outputs 10

Upvotes: 1

quamrana
quamrana

Reputation: 39354

There is no good way to convert the output of a print() into values that can be collected.

You just need functions which return values and a loop which collects them:

import random

array = ['a', 'b', 'c', 'd', 'e', 'f']
def choose():
    return random.choice(array)

def repeat(param, func):
    # param stands for the number of times the function is to be called
    return [func() for _ in range(param)]

# ...
# other parts elided

print(repeat(param, choose))

The expected output is a list which you can examine or manipulate further.

Also, see this answer for a way to get the most popular value.

You can use it like this:

def get_max(l):
    return max(l, key=l.count) 

print(get_max(repeat(param,log)))

Upvotes: 4

chepner
chepner

Reputation: 531075

You might want to generalize log to print to a given file, not just standard output.

def log(fh=sys.stdout):
    print(random.choice(array), file=fh)

Then you can make multiple calls that write to a single io.StringIO object, from which you can get a single string containing everything written to the file. Splitting that string on newlines may be sufficient.

my_log = io.StringIO()
repeat(param, lambda: log(my_log))
my_log.seek(0)

for x in my_log:
    print(x.strip())

You could also define your own file-like class that appends its arguments to a list. Something like

class Collector:
    def __init__(self):
         self.lines = []
    def write(self, line):
        self.lines.append(line)

    def __iter__(self):
        yield from self.lines

my_log = Collector()
repeat(param, log(my_log))

# my_log.lines is just a list of the strings produced by each call to log

Upvotes: 2

user15801675
user15801675

Reputation:

You can do the following:

  1. return the value from log function
  2. Use collections.counter to get the most common element.
import collections
....
def log():
    return random.choice(array)

....
def get_max(l):
    return max(collections.Counter(l))
def repeat(times, func):
    return [func() for i in range(times)]

print(get_max(repeat(param,log)))

Upvotes: 2

Related Questions