I want to generate 111122223333.... A sequence of numbers, each number appearing the same number of times, up to a certain number.
I use python for loop to generate the number sequence, but it cost too much time when the end number is 7000.
import pandas as pd
startNum = 1
endNum = 7000
sequence = []
for i in range(endNum):
for j in range(endNum):
sequence.append(i)
print(i)
So what should i do to reduce time, and get my sequence? no matter method, not include excel.Thanks!
I'd like to get the number sequcency 111122223333
So your code is not really doing what you're asking, so I'll add a few comments on what your code does to understand where it's not working, and provide you with an answer that does what you want.
import pandas as pd
startNum = 1
endNum = 7000
sequence = []
for i in range(endNum): # Here you are looping from 1 to endNum = 7000
for j in range(endNum): # Here you are looping from 1 to endNum = 7000
sequence.append(i) # You are adding i (7000 times because of your previous loop)
print(i) # You probably mean to print sequence ?
You probably want the second loop to be run on the number of repeating characters that you want (which is 4).
Here's the code that does what you want:
startNum = 1
endNum = 7000
sequence = []
repeat = 4
for i in range(endNum):
for _ in range(repeat):
sequence.append(i)
print(sequence)
In your case, I'd prefer using extend and list comprehension (both codes are equivalent):
startNum = 1
endNum = 7000
sequence = []
repeat = 4
for i in range(endNum):
sequence.extend([i for _ in range(repeat)])
i don't know what for but
endnum = 7
''.join([f"{str(i)*4}" for i in range(endnum)])
print(result)
result
0000111122223333444455556666
and it takes less then 1s with endnum = 7000
0:00:00.006550
You can try this:
startNum = 1
endNum = 5
seq = [ (str(i+1))*endNum for i in range(endNum) ]
print("".join(seq))
Related
import random as rd
n = 0
ListOfStreaks = []
ListOfResults = []
while n != 10:
numberOfStreaks = 0
for i in range(100):
Flip = rd.randint(0,1)
ListOfResults.append(Flip)
for i in range(96):
count = 0
for j in range(6):
if ListOfResults[i] == ListOfResults[i + j]:
count += 1
if count == 6:
numberOfStreaks += 1
count = 0
else:
continue
else:
break
ListOfStreaks.append(numberOfStreaks)
n += 1
print(ListOfStreaks)
print(len(ListOfResults))
In the code above, I am able to successfully flip a coin 100 times, and examine how many times in the 100 flips Heads or Tails came up six time in a row. I am unable to properly set up the code to run the experiment 10 times in order to examine how many times Heads or Tails came up six times in a row in each of the single experiments. The goal is to not flip the coins 1,000 times in a row but 10 experiments of flipping 100 coins in a row.
The exercise focuses on later being able to simulate the experiment 10,000 times in order to see what the probability is of Heads or Tails appearing six times in a row in 100 flips. Essentially, I am trying to gather enough of a sample size. While there are actual statistical/probability methods to get the exact answer, that isn't what I am trying to focus on.
CoinFlip Code
Your key problem appears to be that you have ListOfResults = [] outside of your while loop, so each run adds another 100 entries to the list instead of setting up a new test.
I've replaced the initial for loop with a list comprehension which sets up a new sample each time.
import random as rd
list_of_streaks = []
for _ in range(10):
list_of_results = [rd.randint(0,1) for _ in range(100)]
number_of_streaks = 0
for i in range(96):
if sum(list_of_results[i: i+6]) in(0, 6):
number_of_streaks += 1
list_of_streaks.append(number_of_streaks)
print(list_of_streaks)
print(len(list_of_results))
You also don't need the inner for loop to add up all of the 6 flips - you can just sum them to see if the sum is 6 or 0. You appear to have just tested for heads - I tested for 6 identical flips, either heads or tails, but you can adjust that easily enough.
It's also much easier to use a for loop with a range, rather than while with a counter if you are iterating over a set number of iterations.
The first comment from #JonSG is also worth noting. If you had set up the individual test as a function, you'd have been forced to have ListOfResults = [] inside the function, so you would have got a new sample of 100 results each time. Something like:
import random as rd
def run_test():
list_of_results = [rd.randint(0,1) for _ in range(100)]
number_of_streaks = 0
for i in range(96):
if sum(list_of_results[i: i+6]) in(0, 6):
number_of_streaks += 1
return number_of_streaks
print([run_test() for _ in range(10)])
print(len(list_of_results))
I have a array of items with a weight assigned to each item. I want to split it into equal sized chunks of approx. equal cumulative weight. There is an answer here to do this using numpy https://stackoverflow.com/a/33555976/10690958
Is there a simple way to accomplish this using pure python ?
Example array:
[ ['bob',12],
['jack,6],
['jim',33],
....
]
or
a, 11
b,2
c, 5
d, 3
e, 3
f, 2
Here the correct output would be (assuming 2 chunks needed)
[a,11],[b,2] - cumulative weight of 13
and
[c,5],[d,3],[e,3],[f,2] - cumulative weight of 13
To further clarify the question, imagine a situation of sorting a 100 people into 10 elevators, where we want each elevator to have the same approx. total weight (sum of weights of all people in that elevator). So then the first list would become names and weights. Its a load-balancing problem.
You just have to mimic cumsum: build a list summing the weights. At the end you get the total weight. Scan the list with the cumulated weight, and create a new chunk each time you reach total_weight/number_of_chunks. Code could be:
def split(w_list, n_chunks):
# mimic a cumsum
s = [0,[]]
for i in w_list:
s[0]+= i[1]
s[1].append(s[0])
# now scan the lists populating the chunks
index = 0
splitted = []
stop = 0
chunk = 1
stop = s[0] / n_chunks
for i in range(len(w_list)):
# print(stop, s[1][i]) # uncomment for traces
if s[1][i] >= stop: # reached a stop ?
splitted.append(w_list[index:i+1]) # register a new chunk
index = i+1
chunk += 1
if chunk == n_chunks: # ok we can stop
break
stop = s[0] * chunk / n_chunks # next stop
splitted.append(w_list[index:]) # do not forget last chunk
return splitted
You need something like this split:
array =[ ['bob',12],
['jack',6],
['jim',33],
['bob2',1],
['jack2',16],
['jim2',3],
['bob3',7],
['jack3',6],
['jim3',1],
]
array = sorted(array, key= lambda pair: pair[1], )
summ = sum(pair[1] for pair in array )
chunks = 4
splmitt = summ // chunks
print(array)
print(summ)
print(splmitt)
def split(array, split):
splarr = []
tlist = []
summ = 0
for pair in array:
summ += pair[1]
tlist.append(pair)
if summ > split:
splarr.append(tlist)
tlist = []
summ = 0
if tlist:
splarr.append(tlist)
return splarr
spl = split(array, splmitt)
import pprint
pprint.pprint(spl)
I am trying to write my own code for generating permutation of items represented by numbers. Say 4 items can be represented by 0,1,2,3
I've seen the code from itertools product. That code is pretty neat. My way of coding this is using binary or ternary,... My code below only works for bits of less than 10. Part of this code split the str using list(s). Number 120 in base 11 is 1010, splitting '1010' yields, 1,0,1,0. For it to work correctly, I need to to split to 10, 10. Is there a way around this and still work with the rest of the code?
Alternatively, what is a recursive version for this? Thanks
aSet = 11
subSet = 2
s = ''
l = []
number = aSet**subSet
#finding all permutation, repeats allowed
for num in range(number):
s = ''
while num//aSet != 0:
s = str(num%aSet) + s
num = num//aSet
else:
s = str(num%aSet) + s
s = s.zfill(subSet)
l.append(list(s))
Indeed, the problem with using a string, is that list(s) will chop it into individual characters. You should not create a string at all, but use a list for s from the start:
aSet = 11
subSet = 2
l = []
number = aSet**subSet
#finding all permutation, repeats allowed
for num in range(number):
s = []
for _ in range(subSet):
s.insert(0, num%aSet)
num = num//aSet
l.append(s)
Please help for task with the list in Python my logic is bad works:( .
This is full text of task: Write a program that takes a list of
numbers on one line and displays the values in a single row, are
repeated in it more than once.
To solve the problem can be useful sort method list.
The procedure for withdrawal of repetitive elements may be arbitrary.
My beginning code is :
st = (int(i) for i in input().split())
ls = []
for k in st:
if k == k + 1 and k > 1:
Task is : if we have replay value in list we must print it. We only can use sort() method and without any modules importing.
Results Examples:
Sample Input 1:
4 8 0 3 4 2 0 3
Sample Output 1:
0 3 4
Sample Input 2:
10
Sample Output 2:
Sample Input 3:
1 1 2 2 3 3
Sample Output 3:
1 2 3
This code isn't run( sort() function doesn't want sort my_list. But I must input values like my_list = (int(k) for k in input().split())
st = list(int(k) for k in input())
st.sort()
for i in range(0,len(st)-1):
if st[i] == st[i+1]:
print(str(st[i]), end=" ")
my_list = (int(k) for k in input().split())
After running this line, my_list is a generator, something that will create a sequence - but hasn't yet done so. You can't sort a generator. You either need to use []:
my_list = [int(k) for k in input().split()]
my_list.sort()
which makes my_list into a list from the start, instead of a generator, or:
my_list = list(int(k) for k in input().split()))
my_list.sort()
gather up the results from the generator using list() and then store it in my_list.
Edit: for single digits all together, e.g. 48304, try [int(k) for k in input()]. You can't usefully do this with split().
Edit: for printing the results too many times: make the top of the loop look backwards a number, like this, so if it gets to the second or third number of a repeating number, it skips over and continues on around the loop and doesn't print anything.
for i in range(0,len(st)-1):
if st[i] == st[i-1]:
continue
if st[i] == st[i+1]:
print...
st = (int(i) for i in input().split())
used = []
ls = []
for k in st:
if k in used: # If the number has shown up before:
if k not in used: ls.append(k) # Add the number to the repeats list if it isn't already there
else:
used.append(k) # Add the number to our used list
print ' '.join(ls)
In summary, this method uses two lists at once. One keeps track of numbers that have already shown up, and one keeps track of second-timers. At the end the program prints out the second-timers.
I'd probably make a set to keep track of what you've seen, and start appending to a list to keep track of the repeats.
lst = [num for num in input("prompt ").split()]
s = set()
repeats = []
for num in lst:
if num in s and num not in repeats:
repeats.append(num)
s.add(num)
print ' '.join(map(str,repeats))
Note that if you don't need to maintain order in your output, this is faster:
lst = [num for num in input("prompt ").split()]
s = set()
repeats = set()
for num in lst:
if num in s:
repeats.add(num)
s.add(num)
print ' '.join(map(str, repeats))
Although if you can use imports, there's a couple cool ways to do it.
# Canonically...
from collections import Counter
' '.join([num for num,count in Counter(input().split()).items() if count>1])
# or...
from itertools import groupby
' '.join([num for num,group in groupby(sorted(input().split())) if len(list(group))>1])
# or even...
from itertools import tee
lst = sorted(input('prompt ').split())
cur, nxt = tee(lst)
next(nxt) # consumes the first element, putting it one ahead.
' '.join({cur for (cur,nxt) in zip(cur,nxt) if cur==nxt})
this gives the answers you're looking for, not sure if it's exactly the intended algorithm:
st = (int(i) for i in input().split())
st = [i for i in st]
st.sort()
previous = None
for current in st:
if ((previous is None and current <= 1)
or (previous is not None and current == previous + 1)):
print(current, end=' ')
previous = current
>>> "4 8 0 3 4 2 0 3"
0 3 4
>>> "10"
>>> "1 1 2 2 3 3"
1 2 3
updated to:
start with st = (int(i) for i in input().split())
use only sort method, no other functions or methods... except print (Python3 syntax)
does that fit the rules?
I need to break up a length of numbers into chunks of 100 and what ever is left over and then add them to a final dictionary at the end.
I am able to do it with loops but I feel I might be missing something that would make this a much cleaner and efficient operation.
l = 238 # length of list to process
i = 0 #setting up count for while loop
screenNames = {}#output dictionary
count = 0 #count of total numbers processed
while i < l:
toGet = {}
if l - count > 100:#blocks off in chunks of 100
for m in range (0,100):
toGet[count] = m
count = count + 1
else:
k = count
for k in range (0,(l - count)):#takes the remainder of the numbers
toGet[count] = k
count = count + 1
i = l # kills loop
screenNames.update(toGet)
#This logic structure breaks up the list of numbers in chunks of 100 or their
#Remainder and addes them into a dictionary with their count number as the
#index value
print 'returning:'
print screenNames
The above code works but it feels clunky does anyone have any better ways of handling this?
as far as I can see, you map a key n to the value n % 100, so this might be as well written as
screenNames = dict((i, i%100) for i in range(238))
print screenNames
Running your code, it looks like you're just doing modular arithmetic:
l = 238
sn = {}
for i in xrange(l):
sn[i] = i % 100
print sn
Or more succinctly:
l = 238
print dict((i, i % 100) for i in xrange(l))
That works by constructing a dictionary based on key-pair tuples.