only print numbers in list between x and y - python

I'm trying to find out of there is a library I can use to identify if a number is between two numbers, or if I have to iterate through every number with a for loop and an if condition
def get_numbers_in_between(li, x, y):
# x can be bigger than y or vice versa
if x > y:
big = x
small = y
else:
big = y
small = x
nums_in_between = [n for n in li if (n >= small and n <= big)]
return nums_in_between
print(get_numbers_in_between([9, 10, 11, 15, 19, 20, 21], 20, 10))
output:
[10, 11, 15, 19, 20]
Is there a library that will automatically figure out which is bigger/smaller (x,y), and take the list as an input and return a new list with the numbers between?

if you start from a given list and need to extract the ones that satisfy a contition:
lst = [9, 10, 11, 15, 19, 20, 21]
print([n for n in lst if 10 <= n <= 20])
and if you need all the integers its just
list(range(10, 20+1))
if you need to sort the max an min first, this is an option:
def get_numbers_in_between(li, x, y):
mx, mn = sorted((x, y))
return [n for n in li if mx <= n <= mn]
print(get_numbers_in_between(li=[9, 10, 11, 15, 19, 20, 21], x=20, y=10))

Try this :
def get_numbers_in_between(l,x,y):
return [i for i in l if i in range(min(x,y), max(x,y)+1)]
get_numbers_in_between([9, 10, 11, 15, 19, 20, 21], 20, 10) # [10, 11, 15, 19, 20]

Could be as simple as suggested:
small = 8
big = 16
nums_in_between = [n for n in li if n in range(small, big)]

You can use filter,
>>> nums
[9, 10, 11, 15, 19, 20, 21]
>>> sorted_list = sorted(nums) # easier to find min, max ?
>>> min_, max_ = sorted_list[0], sorted_list[-1]
>>> filter(lambda x: min_ < x < max_, nums)
[10, 11, 15, 19, 20]
And there's is similar itertools.ifilter in python2,
>>> import itertools
>>> list(itertools.ifilter(lambda x: 10 <= x <= 20, nums))
[10, 11, 15, 19, 20]
And in itertools.filterfalse in python3,
>>> list(itertools.filterfalse(lambda x: not (10 <= x <= 20), nums))
[10, 11, 15, 19, 20]

with help from roganjosh - good one!
dat=np.random.randint(0,20,50)
x=5
y=10
ans=dat[(dat>=x) & (dat<y)]
print(ans)
old (with np.where):
import numpy as np
dat=np.random.randint(0,20,50)
x=5
y=10
ans=dat[np.where((dat>=x) & (dat<y))]
print(ans)

OP: automatically figure out which is bigger/smaller (x,y), and take the list as an input and return a new list with the numbers between?
Generic method:
def GetNumbersInBetween(lst, l_Bound, u_Bound):
n_List = []
lowerBound = min(l_Bound, u_Bound) # Get the lower val
upperBound = max(l_Bound, u_Bound) # Get the higher val
for x in lst:
if x >= lowerBound and x <= upperBound:
n_List.append(x)
return n_List
lst = [9, 10, 11, 15, 19, 20, 21]
lowerBound = 20 # intentionally given the wrong value
upperBound = 10 # intentionally given the wrong value
print(GetNumbersInBetween(lst, lowerBound, upperBound))
OR
Using list comprehension:
print([x for x in lst if min(lowerBound,upperBound) <= x <= max(lowerBound,upperBound)])
OUTPUT:
[10, 11, 15, 19, 20]

Related

Python: function to group number by tens place

Takes a list of numbers and groups the numbers by their tens place, giving every tens place it's own sublist.
ex:
$ group_by_10s([1, 10, 15, 20])
[[1], [10, 15], [20]]
$ group_by_10s([8, 12, 3, 17, 19, 24, 35, 50])
[[3, 8], [12, 17, 19], [24], [35], [], [50]]
my approach:
limiting = 10
ex_limiting = 0
result = []
for num in lst:
row = []
for num in lst:
if num >= ex_limiting and num <= limiting:
row.append(num)
lst.remove(num)
result.append(row)
ex_limiting = limiting
limiting += 10
But it returns [[1], [10, 20]].
What's wrong with my approach and how can I fix it?
You may already have a correct answer, but here's an alternative solution:
def group_by_10s(mylist):
result = []
decade = -1
for i in sorted(mylist):
while i // 10 != decade:
result.append([])
decade += 1
result[-1].append(i)
return result
group_by_10s([8, 12, 3, 17, 19, 24, 35, 50])
#[[3, 8], [12, 17, 19], [24], [35], [], [50]]
It uses only plain Python, no extra modules.
You can use a list comprehension:
def group_by_10s(_d):
d = sorted(_d)
return [[c for c in d if c//10 == i] for i in range(min(_d)//10, (max(_d)//10)+1)]
print(group_by_10s([1, 10, 15, 20]))
print(group_by_10s([8, 12, 3, 17, 19, 24, 35, 50]))
print(group_by_10s(list(range(20))))
Output:
[[1], [10, 15], [20]]
[[3, 8], [12, 17, 19], [24], [35], [], [50]]
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
Credit to advice for not iterating list during loop.
I got this answer at the end, for anyone who wants the answer.
Thanks for support!
def group_by_10s(numbers):
external_loop = int(max(numbers)/10)
limiting = 10
ex_limiting = 0
result = []
for external_loop_count in range(external_loop+1):
row = []
for num in numbers:
if num >= ex_limiting and num < limiting:
row.append(num)
row.sort()
result.append(row)
ex_limiting = limiting
limiting += 10
return(result)
How about this one?
numbers = [8, 12, 3, 17, 19, 24, 35, 50]
def group_by_10s(numbers):
arr = []
for i in range((max(numbers) / 10) + 1):
arr.append([])
numbers.sort()
for number in numbers:
if number < 10:
arr[0].append(number)
else:
index = number / 10
arr[index].append(number)
return arr
print group_by_10s(numbers)
# [[3, 8], [12, 17, 19], [24], [35], [], [50]]
Do not modify the list while you are iterating over it, as when you remove items from it, some items get skipped over. Also change the bounds so that you will only append to row if num < limiting. I would add in a check to make sure the list has elements before adding it to result:
for num in lst:
row = []
for num in lst:
if num >= ex_limiting and num < limiting:
row.append(num)
if len(row) > 0 :
result.append(row)
ex_limiting = limiting
limiting += 10
This will yield:
[[1], [10, 15], [20]]

how to get list of numbers by adding or subtracting given 4 numbers in python

I am trying to get possible numbers from 1 to n, given 4 numbers. by adding or subbtracting 2 or more of the 4 numbers.
e.g. it goes into loop for numlist(1,2,3,16). Below is the code:
def numlist(a,b,c,d):
#user input of 4 numbers a,b,c,d
# assigning variables value of -1. This will be used to provide -1 or +1 or 0
p=-1
q=-1
r=-1
s=-1
count=0
myarray=[]
mysum=a+b+c+d #sum of given 4 numbers
for x in range(mysum):
while count<mysum:
if p<=1:
if q<=1:
if r <=1:
if s<=1:
n1=p*a+q*b+r*c+s*d #number to be generated by adding/subtracting
s=s+1
#print(n1)
if n1>0 and (n1 in myarray)==False:
#print(n1)
myarray.append(n1) #add to myarray if number is positive and not already present
myarray.sort() #sort myarray
count=count+1
if count==mysum:
break
else:
s=-1
r=r+1
else:
r=-1
q=q+1
else:
q=-1
p=p+1
else:
p=-1
print(len(myarray),'total')
print(myarray)
numlist(1,3,4,14)
outputs
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
but if numlist(1,3,4,19)
it keeps running without ending in output of array. only shows total.
where am I going wrong ?
I think you should rethink your algorithm. Consider this:
from itertools import combinations
def numlist(lst):
lst = lst + [-i for i in lst]
result = set()
for i in range(2, 5):
result.update(sum(k) for k in combinations(lst, i))
return sorted(i for i in result if i > 0)
numlist([1, 3, 4, 19])
# [1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]
I did a little patch-up work, and found the high-level problem with your logic.
Your code goes into an infinite loop when the current value of count cannot be formed with the input values. Your logic fails to increment count until it finds a way to create that value. You spin through one combination after another of coefficients.
for x in range(mysum):
print ("top of loop; x =", x)
while count<mysum:
print("count", count, "\tmysum", mysum, "\tcoeffs", p, q, r, s)
if p<=1:
...

Python FloorOfX Using Binary Search

How do I write the code by using binary search:
def floorofx(L, x):
pass
Like define low, high, middle for each of element. As,
Input: L = [11, 12, 13, 14, 15, 20, 27, 28], x = 17
Output: 15
15 is the largest element in L smaller than 17.
Input: L = [11, 12, 13, 14, 15, 16, 19], x = 20
Output: 19
19 is the largest element in L smaller than 20.
Input: L = [1, 2, 8, 10, 10, 12, 19], x = 0
Output: -1
Since floor doesn't exist, output is -1.
Can someone help me with it?
You can simply use the bisect module and decrement the obtained index.
from bisect import bisect_right
def floorofx(L, x):
idx = bisect_right(L,x)
return L[idx-1] if idx > 0 else -1
This generates the following results (for your given sample input):
>>> floorofx(L = [11, 12, 13, 14, 15, 20, 27, 28], x = 17)
15
>>> floorofx(L = [11, 12, 13, 14, 15, 16, 19], x = 20)
19
>>> floorofx(L = [1, 2, 8, 10, 10, 12, 19], x = 0)
-1
Mind that L must be sorted, and that in case -1 is an element of L, you cannot make the distinction between "not found" and -1 as a result. Since we use binary search, the algorithm runs in O(log n).

How do you enter numbers into a list without any being repeated?

I am trying to make a list with the numbers 1-24 all in it in a random order, why doesn't this work?
full_list = []
x = 0
while x < 25 :
n = randint (1,24)
while n in full_list:
n = randint (1,24)
full_list.append(n)
x = x + 1
random has a shuffle function that would make more sense for this task:
ar = list(range(1,25))
random.shuffle(ar)
ar
> [20, 14, 2, 11, 15, 10, 3, 4, 16, 23, 13, 19, 5, 21, 8, 7, 17, 9, 6, 12, 22, 18, 1, 24]
Also, your solution doesn't work because while x < 25 needs to be while x < 24. It is in an infinite loop when x = 24 (since randint(1,24) will never generate a new number not in the list).

Multiplying two sets of numbers in python

I have two lists of numbers, say [1, 2, 3, 4, 5] and [7, 8, 9, 10, 11], and I would like to form a new list which consists of the products of each member in the first list with each member in the second list. In this case, there would be 5*5 = 25 elements in the new list.
I have been unable to do this so far with a while() loop.
This is what I have so far:
x = 0
y = 99
results = []
while x < 5:
x = x + 1
results.append(x*y)
while y < 11:
y = y + 1
results.append(x*y)
Use itertools.product to generate all possible 2-tuples, then calculate the product of that:
[x * y for (x, y) in itertools.product([1,2,3,4,5], [7,8,9,10,11])]
The problem is an example of an outer product. The answer already posted with itertools.product is the way I would do this as well.
But here's an alternative with numpy, which is usually more efficient than working in pure python for crunching numeric data.
>>> import numpy as np
>>> x1 = np.array([1,2,3,4,5])
>>> x2 = np.array([7,8,9,10,11])
>>> np.outer(x1,x2)
array([[ 7, 8, 9, 10, 11],
[14, 16, 18, 20, 22],
[21, 24, 27, 30, 33],
[28, 32, 36, 40, 44],
[35, 40, 45, 50, 55]])
>>> np.ravel(np.outer(x1,x2))
array([ 7, 8, 9, 10, 11, 14, 16, 18, 20, 22, 21, 24, 27, 30, 33, 28, 32,
36, 40, 44, 35, 40, 45, 50, 55])
Wht dont you try with known old ways;
list1 = range(1, 100)
list2 = range(10, 50, 5)
new_values = []
for x in list1:
for y in list2:
new_values.append(x*y)
Without any importing, you can do:
[x * y for x in range(1, 6) for y in range(7, 12)]
or alternatively:
[[x * y for x in range(1, 6)] for y in range(7, 12)]
To split out the different multiples, but it depends which order you want the results in.
from functools import partial
mult = lambda x, y: x * y
l1 = [2,3,4,5,5]
l2 = [5,3,23,4,4]
results = []
for n in l1:
results.extend( map( partial(mult, n) , l2) )
print results

Categories