Related
Here, I have a list of random integers:
import random
list = [random.randint(0, 30) for x in range(6)]
pass
I want to double the size of this list, sort it, and print it. Here's what I've tried:
def list_doubled(list):
doubled = []
i = 0
while i <= len(list):
for item in list:
doubled.append(list[i])
doubled.append(list[i])
i += 1
print(doubled)
list_doubled(list)
This code is meant to only double the size of the list. When I run the program, I get "IndexError: list index out of range" with emphasis on lines 11 and 16.
In Python you can double a list by just multiplying it by 2.
>>> import random
>>> nums = [random.randint(0, 30) for _ in range(6)]
>>> print(nums)
[5, 30, 28, 11, 19, 17]
>>> print(sorted(nums * 2))
[5, 5, 11, 11, 17, 17, 19, 19, 28, 28, 30, 30]
Creating the list:
import random
numbers = [random.randint(0, 30) for x in range(6)]
Use extend to add the list to itself, in order to double it:
numbers.extend(numbers) # or numbers += numbers
Or add as many random numbers as there are items in the list, if you need the additional numbers to also be random:
numbers.extend(random.randint(0, 30) for _ in range(len(numbers)))
use sort to sort it:
numbers.sort()
Use print to print it:
print(numbers)
Change your <= to < in your while loop line while i <= len(list):. You also might want to look at the comments, they have good advise on additional potential bugs you might encounter.
L = [random.randint(0,50) for i in range(5) random.randint(0,12) for i in range(2)]
How do I get it to pick 5 random numbers between (0,50), then 2 random numbers between(0,12)?
You can vary the second argument to randint() based on the value of i:
[randint(0, 50 if i < 5 else 12) for i in range(7)]
The 50 if i < 5 else 12 expression will change what is passed to random.randint() for the last two iterations.
There are many more variations you can spell this in. List comprehensions are a bunch of loops and if filters that repeatedly execute the expression at the front. There are lots of ways to spell vary the arguments to a function call based on the iteration values in expressions.
For example, you could record those arguments in functools.partial() objects:
from functools import partial
from random import randint
rint50 = partial(randint, 0, 50)
rint12 = partial(randint, 0, 12)
[rint() for rint in [rint50] * 5 + [rint12] * 2]
The possibilities are endless. Lambdas, randint(0, upperbound), randint(*args), a function that'll vary its results depending on how often it has been called, etc. But I wouldn't argue that any of these are actually more readable or understandable.
For this case, with just 7 values, I'd just concatenate the two lists:
[randint(0, 50) for _ in range(5)] + [randint(0, 12) for _ in range(2)]
as it's just cleaner and more readable. The small performance cost of creating a 3rd list that contains the results of the two list comprehensions is negligible here.
Something like this maybe, concatenating 2 lists:
from random import randint
my_list = [randint(0,50) for i in range(5)] + [randint(0,12) for i in range(2)]
Don't reuse the name list. One way would be to loop through an iterable of the bounds, and send those to randint
from random import randint
lst = [randint(*bounds) for bounds in [(0, 50)]*5 + [(0, 12)]*2]
You could also use itertools.chain and itertools.repeat to avoid building that list of bounds
lst = [randint(*bounds) for bounds in chain(repeat((0, 50), 5), repeat((0, 12), 2))]
import random
l = [random.randint(0,50) for i in range(5)]
l.extend([random.randint(0,12) for i in range(2)])
print(l)
Here's another variation that avoids doing an if test on every iteration. It also uses randrange, which is slightly more efficient than randint.
from random import randrange
lst = [randrange(hi) for num, hi in ((5, 51), (2, 13)) for _ in range(num)]
print(lst)
typical output
[10, 31, 46, 25, 23, 6, 5]
This is equivalent to
lst = []
for num, hi in ((5, 51), (2, 13)):
for _ in range(num):
lst.append(randrange(hi))
The outer loop selects num, the number of items in the sublist, and hi the size of the random range for that sublist; the inner loop generates the required amount of random numbers in the desired range.
FWIW, here's some timeit code comparing the various algorithms that have been submitted. It also verifies that they produce the same results when given the same random seed. My simple verification code uses eval, so it can only test expressions, not statements, so it can't test jpp's or Abhishek's code; besides, jpp's Numpy code gives different results anyway, since it uses a different seeding algorithm. Please see the timeit docs for info on what timeit does, and how to interpret the results.
from timeit import Timer
import random
from random import randint, randrange, seed
from itertools import chain, repeat, starmap
from functools import partial
import numpy as np
imports = 'random, randint, randrange, seed, chain, repeat, starmap, partial, np'
commands = (
('Martijn', '', '[randint(0, 50 if i < 5 else 12) for i in range(7)]'),
('Martijn_partial',
'rint50 = partial(randint, 0, 50); rint12 = partial(randint, 0, 12)',
'[rint() for rint in [rint50] * 5 + [rint12] * 2]'
),
('Patrick', '', '[randint(*bounds) for bounds in [(0, 50)]*5 + [(0, 12)]*2]'),
('Patrick_chain', '',
'[randint(*bounds) for bounds in chain(repeat((0, 50), 5), repeat((0, 12), 2))]'
),
('Ralf', '', '[randint(0,50) for i in range(5)] + [randint(0,12) for i in range(2)]'),
('Abhishek', '', 'l = [random.randint(0,50) for i in range(5)];'
'l.extend([random.randint(0,12) for i in range(2)])'
),
('PM 2Ring', '', '[randrange(hi) for num, hi in ((5, 51), (2, 13)) for _ in range(num)]'),
('jpp', '', 'A = np.zeros(7); '
'A[:5] = np.random.randint(0, 20, 5); A[5:] = np.random.randint(0, 12, 2)'
),
('Tanmay jain', '',
'[random.randint(0,50) if i < 5 else random.randint(0,12) for i in range(7)]'
),
('juanpa', '', '[random.randint(a,b) for args in (((0,50) for _ in range(5)),'
'((0, 12) for _ in range(2))) for a, b in args]'
),
('juanpa_starmap', '', 'list(starmap(random.randint,'
'chain(repeat((0,50),5), repeat((0,12),2))))'
),
)
def verify():
for name, setup, cmd in commands:
if name in ('jpp', 'Abhishek'):
continue
seed(17)
if setup:
exec(setup)
print('{:16}: {}'.format(name, eval(cmd)))
print()
def time_test(loops):
timings = []
print('loops =', loops)
for name, setup, cmd in commands:
setup = 'from __main__ import ' + imports + ';' + setup
t = Timer(cmd, setup=setup)
result = sorted(t.repeat(3, loops))
timings.append((result, name))
timings.sort()
for result, name in timings:
print('{:16} : {}'.format(name, result))
verify()
time_test(5000)
typical output
Martijn : [33, 26, 19, 23, 18, 2, 12]
Martijn_partial : [33, 26, 19, 23, 18, 2, 12]
Patrick : [33, 26, 19, 23, 18, 2, 12]
Patrick_chain : [33, 26, 19, 23, 18, 2, 12]
Ralf : [33, 26, 19, 23, 18, 2, 12]
PM 2Ring : [33, 26, 19, 23, 18, 2, 12]
Tanmay jain : [33, 26, 19, 23, 18, 2, 12]
juanpa : [33, 26, 19, 23, 18, 2, 12]
juanpa_starmap : [33, 26, 19, 23, 18, 2, 12]
loops = 5000
jpp : [0.23938178099342622, 0.24184146700281417, 0.3152835669970955]
PM 2Ring : [0.26918871099769603, 0.27244400099880295, 0.2916741489971173]
Patrick : [0.34155847399961203, 0.34415175200410886, 0.3531294650019845]
juanpa_starmap : [0.3417540490045212, 0.34329504700144753, 0.3438059809996048]
Martijn : [0.3509639670010074, 0.362117896998825, 0.547288200003095]
Martijn_partial : [0.3511254819968599, 0.35262946599686984, 0.39430355399963446]
Patrick_chain : [0.3541102219969616, 0.3545923809942906, 0.3555165420038975]
Tanmay jain : [0.3558294050017139, 0.5510739650053438, 0.7693202439986635]
Ralf : [0.3678122450000956, 0.44522786799643654, 0.44827762299973983]
juanpa : [0.4089203829935286, 0.41227930299646687, 0.42410747800022364]
Abhishek : [0.4811078249986167, 0.4942625819967361, 0.6255962599971099]
As you can see, jpp's Numpy code is the fastest. I expect that the speed difference would be even more apparent if we were generating a longer list of numbers.
These timing were performed on an ancient 32 bit single core 2GHz machine, running Python 3.6.0 on a Debian derivative distro. YMMV.
Here are timings for the production of lists (or arrays) of 50 + 20 = 70 values in the same ranges.
loops = 500
jpp : [0.025625186994147953, 0.025764200996491127, 0.03122780400008196]
PM 2Ring : [0.21989007600495825, 0.2200367909972556, 0.22065802400175016]
juanpa_starmap : [0.3094131350007956, 0.3110805670003174, 0.31563361900043674]
Patrick_chain : [0.3122365829985938, 0.31262181099737063, 0.3137894630053779]
Patrick : [0.3130071220002719, 0.31769691400404554, 0.3179219129960984]
Ralf : [0.31566168300196296, 0.3157304769993061, 0.3234770689959987]
Martijn : [0.3193310350034153, 0.3275600470005884, 0.35491854500287445]
Martijn_partial : [0.321399387998099, 0.3226969290044508, 0.32442738999816356]
Abhishek : [0.32655813400197076, 0.3363869300010265, 0.3657162370000151]
Tanmay jain : [0.32833286200184375, 0.33107244400162017, 0.39565577400207985]
juanpa : [0.35968791200139094, 0.3754627199959941, 0.3933205349967466]
If you are happy using a 3rd party library, you can via NumPy:
import numpy as np
np.random.seed(0) # for consistency / testing
A = np.zeros(7)
A[:5] = np.random.randint(0, 20, 5)
A[5:] = np.random.randint(0, 12, 2)
array([ 12., 15., 0., 3., 3., 7., 9.])
The benefit of this method, memory pre-allocation, will be evident with larger arrays.
since you want to pick 5 random values from 0 - 50( exclusive)
i = 0...4
and then you want to pick 2 random values from 0 - 12( exclusive)
i = 5 6
lst = [random.randint(0,50) if i < 5 else random.randint(0,12) for i in range(7)]
print(lst) # [7, 10, 40, 4, 38, 1, 5]
You can do this using list-comprehensions and only built-ins, some monstrosity like:
>>> result = [
... random.randint(a,b)
... for args in (((0,50) for _ in range(5)), ((0, 12) for _ in range(2)))
... for a, b in args
... ]
>>> result
[33, 38, 19, 9, 47, 0, 8]
Perhaps, if you want to use itertools, you can do something like:
>>> from itertools import chain, repeat, starmap
>>> list(starmap(random.randint, chain(repeat((0,50),5), repeat((0,12),2))))
[16, 47, 40, 21, 15, 12, 4]
Both of these approaches are hardly readable and simple. Instead, I would personally go with two for-loops, the naive approach. It would be efficient, simple, and readable. Other than showboating, I see no advantage to the above approaches in production code.
In variable noprimes what is the use of declaring second i in j loop? Is it taking values from first i loop or referencing i values?
>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
>>> primes = [x for x in range(2, 50) if x not in noprimes]
>>> print primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
Think of it as a double for loop. It might be easier to understand if you read it like this:
[j for j in range(i*2, 50, i) for i in range(2, 8)] # **Not valid Python!**
or this:
noprimes = []
for i in range(2, 8):
for j in range(2 * i, 50, i):
noprimes.append(j)
In the first outer loop iteration, i is 2 and therefore j runs the range(4, 50, 2) range. As a result, the numbers (js) it produces are the following:
j = [4, 6, ..., 48]
In the next iteration, i = 3 and the new js are:
j = [6, 9, ..., 48]
And so on until i = 7. Finally, you put all these js together creating the noprimes list.
This is simply an implementation of Eratosthenes Sieve. It collects all the multiples of (numbers up to 7) up to 50 and everything that is not included in there is a prime.
I'm trying to write a code that lets me find the first few multiples of a number. This is one of my attempts:
def printMultiples(n, m):
for m in (n,m):
print(n, end = ' ')
I figured out that, by putting for m in (n, m):, it would run through the loop for whatever number was m.
def printMultiples(n, m):
'takes n and m as integers and finds all first m multiples of n'
for m in (n,m):
if n % 2 == 0:
while n < 0:
print(n)
After multiple searches, I was only able to find a sample code in java, so I tried to translate that into python, but I didn't get any results. I have a feeling I should be using the range() function somewhere in this, but I have no idea where.
If you're trying to find the first count multiples of m, something like this would work:
def multiples(m, count):
for i in range(count):
print(i*m)
Alternatively, you could do this with range:
def multiples(m, count):
for i in range(0,count*m,m):
print(i)
Note that both of these start the multiples at 0 - if you wanted to instead start at m, you'd need to offset it by that much:
range(m,(count+1)*m,m)
Does this do what you want?
print range(0, (m+1)*n, n)[1:]
For m=5, n=20
[20, 40, 60, 80, 100]
Or better yet,
>>> print range(n, (m+1)*n, n)
[20, 40, 60, 80, 100]
For Python3+
>>> print(list(range(n, (m+1)*n, n)))
[20, 40, 60, 80, 100]
Based on mathematical concepts, I understand that:
all natural numbers that, divided by n, having 0 as remainder, are all multiples of n
Therefore, the following calculation also applies as a solution (multiples between 1 and 100):
>>> multiples_5 = [n for n in range(1, 101) if n % 5 == 0]
>>> multiples_5
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
For further reading:
https://www.mathsisfun.com/definitions/natural-number.html
https://www.mathwizz.com/arithmetic/help/help9.htm
https://www.calculatorsoup.com/calculators/math/multiples.php
For the first ten multiples of 5, say
>>> [5*n for n in range(1,10+1)]
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
You can do:
def mul_table(n,i=1):
print(n*i)
if i !=10:
mul_table(n,i+1)
mul_table(7)
If this is what you are looking for -
To find all the multiples between a given number and a limit
def find_multiples(integer, limit):
return list(range(integer,limit+1, integer))
This should return -
Test.assert_equals(find_multiples(5, 25), [5, 10, 15, 20, 25])
Another method that can be done is trying to make a list. Here's my example for getting the first 20 multiples of 7.
Input:
multiples_7 = [x * 7 for x in range(1,21)]
print(multiples_7)
Output:
[7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140]
def multiples(n,m,starting_from=1,increment_by=1):
"""
# Where n is the number 10 and m is the number 2 from your example.
# In case you want to print the multiples starting from some other number other than 1 then you could use the starting_from parameter
# In case you want to print every 2nd multiple or every 3rd multiple you could change the increment_by
"""
print [ n*x for x in range(starting_from,m+1,increment_by) ]
For first 10 multiples of 5 you can do as
import numpy as np
#np.arange(1,11) array from 1 to 10
array_multipleof5 = [5*n for n in np.arange(1,11)]
array_multipleof5 = np.array(array_multipleof5)
print(array_multipleof5)
How to calculate the first n multiples of a given number x, in the compact python's lambda notation
n_multiples_of_x = lambda n,x : list( range(x, x*n + 1, x) )
Tests:
assert n_multiples_of_x(5, 5) == [5, 10, 15, 20, 25]
So I have this list and variables:
nums = [14, 8, 9, 16, 3, 11, 5]
big = nums[0]
spot = 0
I'm confused about how to actually do it. I want to use this exercise to give me a starter. How do I do that on Python?
Usually, you could just use
max(nums)
If you explicitly want to use a loop, try:
max_value = None
for n in nums:
if max_value is None or n > max_value: max_value = n
Here you go...
nums = [14, 8, 9, 16, 3, 11, 5]
big = max(nums)
spot = nums.index(big)
This would be the Pythonic way of achieving this. If you want to use a loop, then loop with the current max value and check if each element is larger, and if so, assign to the current max.
nums = [14, 8, 9, 16, 3, 11, 5]
big = None
spot = None
for i, v in enumerate(nums):
if big is None or v > big:
big = v
spot = i
Python already has built in function for this kind of requirement.
list = [3,8,2,9]
max_number = max(list)
print (max_number) # it will print 9 as big number
however if you find the max number with the classic vay you can use loops.
list = [3,8,2,9]
current_max_number = list[0]
for number in list:
if number>current_max_number:
current_max_number = number
print (current_max_number) #it will display 9 as big number
Why not simply using the built-in max() function:
>>> m = max(nums)
By the way, some answers to similar questions might be useful:
Pythonic way to find maximum value and its index in a list?
How to find all positions of the maximum value in a list?
To address your second question, you can use a for loop:
for i in range(len(list)):
# do whatever
You should note that range() can have 3 arguments: start, end, and step. Start is what number to start with (if not supplied, it is 0); start is inclusive.. End is where to end at (this has to be give); end is exclusive: if you do range(100), it will give you 0-99. Step is also optional, it means what interval to use. If step is not provided, it will be 1. For example:
>>> x = range(10, 100, 5) # start at 10, end at 101, and use an interval of 5
>>> x
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] # note that it does not hit 100
Since end is exclusive, to include 100, we could do:
>>> x = range(10, 101, 5) # start at 10, end at 101, and use an interval of 5
>>> x
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] # note that it does hit 100
For the Max in List Code HS I've managed to get most of the auto grader to work for me using this code:
list = [-3,-8,-2,0]
current_max_number = list[0]
for number in list:
if number>current_max_number:
current_max_number = number
print current_max_number
def max_int_in_list():
print "Here"
I'm not sure where the max_int_in_list goes though. It needs to have exactly 1 parameter.
To print the Index of the largest number in a list.
numbers = [1,2,3,4,5,6,9]
N = 0
for num in range(len(numbers)) :
if numbers[num] > N :
N = numbers[num]
print(numbers.index(N))
student_scores[1,2,3,4,5,6,7,8,9]
max=student_scores[0]
for n in range(0,len(student_scores)):
if student_scores[n]>=max:
max=student_scores[n]
print(max)
# using for loop to go through all items in the list and assign the biggest value to a variable, which was defined as max.
min=student_scores[0]
for n in range(0,len(student_scores)):
if student_scores[n]<=min:
min=student_scores[n]
print(min)
# using for loop to go through all items in the list and assign the smallest value to a variable, which was defined as min.
Note: the above code is to pick up the max and min by using for loop, which can be commonly used in other programming languages as well. However, the max() and min() functions are the easiest way to use in Python to get the same results.
I would add this as a reference too. You can use the sort and then print the last number.
nums = [14, 8, 9, 16, 3, 11, 5]
nums.sort()
print("Highest number is: ", nums[-1])
scores = [12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27,
28, 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 31, 31, 37,
56, 75, 23, 565]
# initialize highest to zero
highest = 0
for mark in scores:
if highest < mark:
highest = mark
print(mark)