问题
I have a fairly big loop that needs to run 500 times, and I'm new to using the programming language and doing this type of simulation.
But I need to document the results of each run, and if the list (table1) contains either all 0's, all 1's or a mix of both.
I was just wondering what method would be the fastest to find out what proportion of the 500 simulations, resulted in a list that contained all 0's, all 1's or a mix and if append would slow it down too much.
for x in range(0, 500):
times = 300
gamma_val = 2
table1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
total = 0.0
while total < times:
table = [0 for i in range (21)]
for d1 in range(21):
if table1[d1]:
table[d1] = -(1/gamma_val)*math.log((random.random()))
else:
table[d1] = -(math.log(random.random()))
####Goes on to make new table1 with changes, either all 1's, all 0's or a mix of 0s #########and 1s
files1 = 0
files01 = 0
files0 = 0
if "1" "0" in table1 == True:
files01 += 1
elif 1 in table == True:
files1 += 1
elif 0 in table1 == true:
files0 += 1
回答1:
For choosing where to append, create 2 boolean vars (Has1s and Has0s) before the while loop, each initialized to False. Set Has1s to True whenever you get a 1 & Has0s when you get a 0 -- then you avoid the (up to) 3 searches at the end.
回答2:
What exactly do you need at the end?
If you just want to know the proportion of all 1's, all 0's, or mixes, it seems more intuitive (to me at least) to just increment variable values, rather than generate lists. If you set up the code something like:
...
files1=0
files01=0
files0=0
if 1 in table1 and 0 in table1:
files01 += 1
elif 1 in table:
files1 += 1
elif 0 in table1:
files0 += 1
...
then you don't have to do a len(files01)
at the end to know how many had a mix of 1's and 0's.
回答3:
There is no speed lost to append()
, compared to the speed lost to scanning over things multiple times. And there is very little time lost to memory operations compared to the computations. So don't worry about it. I might not keep the counts, if I can get them from the lengths of the lists you want to accumulate anyway. It is more readable to do everything once. Make the stuff, and then count.
I trust the standard containers relative to making decisions about speed of algorithms. So I would cast the row to a Set and compare to the Set([0]), Set([1]), and Set([0,1]). I assume 'in' will do a double scan of the row, whereas Set() will make one pass.
BOTH = set([0, 1])
results = {'0': [], '1': [], '01': []}
.... make the list ....
elements = set(table)
if elements == BOTH:
results['01'].append(table)
else if 1 in elements:
results['1'].append(table)
else:
results['0'].append(table)
And I will try to make my picking about style, not outright errors:
Use the final else, don't exhaust all the conditions; it really is more readable. Exhausting them all separately makes readers wonder what case you imagine might be left. It breeds paranoia.
In general, actually comparing things to True or False is non-pythonic. Checking equality to the constant True is the least reliable way to get what you want out of an condition in Python. There are a lot of Python idioms that rely on the truth of a statement being represented by the existence of an object, or the non-emptyness of a list. So you will face programmers who return something other than True or False from helper functions to represent Boolean determinations. Get used to not being finicky about it.
Also, painful as it seems, in when mixed with other comparison operators chains as though it meant <, which is so non-idiomatic for non-analysts that you should never do it.
来源:https://stackoverflow.com/questions/9201445/best-way-to-keep-track-of-results-from-a-python-loop