i am trying to write a code as part of a simulator that will read a list of numbers and compare them to a secondary list of numbers and tell you how many numbers there are that are less then the first number. for example
X=[5,20,14,1,7]
Y=[2,12,9,5,4,6]
the code will take the first X value 5 and see how many of the Y values are less then 5. so the output Z would look something like
Z=[2,6,6,0,4]
i am not very familiar with these concepts at all, i am wondering how i would go about making a function for this type of work. how would i make a for loop that would go through and compare the numbers like that? also is it possible to combine and sort the lists from smallest to largest and then just search that list for the X value and print its position in the list?
Something like:
[len(list(filter(lambda k: k<m, Y))) for m in X]
You can do it using map and list comprehension in one line:
first = [5, 20, 14, 1, 7]
second = [2, 12, 9, 5, 4, 6]
z = map(lambda x: len([y for y in second if x > y]), first)
or without lambda (as #RobertB wrote):
z = [sum([x > y for y in second]) for x in first]
Result is:
[2, 6, 6, 0, 4]
There are many ways to go about the above question. I will explain the easiest method, although it is not the most efficient method
Concept: Nested For Loop
for x in range (0, a1_len-1):
for y in range (0, a2_len -1):
if a[y] < a[x]:
new_array.append(a[y])
print (new_array)
Hope this helps
Another answer using broadcasting with numpy:
import numpy as np
np.apply_along_axis(np.sum,0,np.array(Y).reshape((len(Y),1))<X)
Related
I'm trying to make a python code to create "double points", where one single value for x would assume two values for y for any situation. Here is a example of data:
1;5
2;-2
3;4
4;10.4
5;6
where first column(x), is just an index for position of the data (y).
Plotting this data into x and y, would form a straight line.
The result I would like to have is:
1;5
1;-2
2;-2
2;4
3;4
3;10.4
4;10.4
4;6
5;6
This would generate a rectangular chart. The value of x has its respective value of y, but that same value of x also has the value of y for its "x + 1", and so for the rest of the data.
I'm trying to do something like this, however unsuccessful:
l = [5, -2, 4, 10.4, 6]
m = []
i = 0
i = i+1
for i in range(len(l)):
m.append(l[i])
if i < len(l)-1:
m.append([l[i][0], l[i+1][1]])
print('{}, {}\n' .format(i, m[i]))
The error that appears is 'int' object has no attribute '__getitem__'
I am new to python and this is part of my studies, so if anyone can help me and can explain where I am going wrong, I would be grateful.
P.s the x column is not part of the data, is just an index (like time for example). And the data (y column) can be negative, floats... all of types of numbers
can be done using list comprehension like below
from itertools import chain
ls = [5, -2, 4, 10.4, 6]
list(chain(*([(i,v)]*2 for i, v in enumerate(ls))))[1:]
Try matching the items on each list depending on their index. E.g. with list.index(item):
y=[5, -2, 4, 10.4, 6]
x=[i for i in range(len(y)+1) if i!=0]
for item in x:
for i in y:
if x.index(item) == y.index(i):
print('%s;%s' %(item, i))
if x.index(item)==y.index(i) -1:
print('%s;%s' %(item, i))
Suppose I want to generate a list of the set of positive integers whose square is less than 100 in python.
My initial thinking was to do something like this
from itertools import count
numbers = [x for x in count() if x**2<100]
However this code won't complete, as python goes through infinitely many numbers.
There are two solutions to this as far as I can tell:
Put in a bound on the range of integers to go over, so use range(1000) instead of count() above.
Use a while loop, incrementing x and stopping the loop when x squared is greater than or equal to 100.
Neither of these solutions are elegant or (as far as I can tell) pythonic. Is there a good way to handle cases like this ,when iterating over an infinite container but you know that the loop stops at some point.
Thanks!
This would be a use case for itertools.takewhile:
from itertools import count, takewhile
numbers = list(takewhile(lambda x: x**2 < 100, count()))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
For a slice of known bounds from a (infinite) generator (not all of those have such simple finite equivalents as range), use itertools.islice:
numbers = list(islice(count(), 4, 10, 2))
# [4, 6, 8]
That being said, and with a loop-based approach being perfectly legit as well, there is a hacky way of achieving it in one line without any library tools, by causing an "artificial" StopIteration:
numbers = list(x if x**2<100 else next(iter([])) for x in count())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
don't do this in serious code though - not just because it will stop working in Python3.7 ;-)
I'd use takewhile:
nums = itertools.takewhile(lambda x: x**2 < 100, count())
Literally, take while the square is less than 100
If you were to use range, I would write it like this.
import math
[x for x in range(int(math.sqrt(100))+1) if (x**2) < 100]
You can change 100 to what you like or set it as a variable, but you know the list of numbers will end at the square root of your target number.
I was reading about arrays and I'm wondering how can I sort the elements from an array from right to left.
For example:
n = 10
numbers = []
for i in range(1, n+1):
numbers.append(i)
print(numbers)
How can I show the components from the last one to the very first one (10, 9, 8...) using basics tools like cycles and conditions?.
And besides this alternative:
for i in range(-1, (-len(numbers) - 1), -1):
print(numbers[i])
You aren't sorting an array. You are attempting to construct one with a particular ordering. You can do this using range directly. range can be invoked with three arguments start, stop and step. This allows you to construct a range 10, 9, ...:
Python 2:
numbers = range(10, 0, -1)
print numbers
Python 3:
numbers = list(range(10, 0, -1))
print(numbers)
output
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Use sorted with reverse=True
sorted(numbers, reverse=True)
or try list.sort method
number.sort(reverse=True)
But in your case you simple can use reverse indexing
number[: : -1]
list(reversed([1,2]))
>> [2,1]
There are many different algorithms to sort arrays without default functions. Here's a list of some of them: https://en.wikipedia.org/wiki/Sorting_algorithm. You can use a sorting algorithm to sort the array, then, reverse it using reversed(list).
If you are looking to have list in reverse you could do this:
In [17]: [4,6,7][::-1]
Out[17]: [7, 6, 4]
You can use the range function for that, like
for i in range(n,0,-1):
print(number[i])
If you want to reverse your list in descending order then you can use the sort method of lists.
number.sort(reverse=True)
I've been writing a program to brute force check a sequence of numbers to look for euler bricks, but the method that I came up with involves a triple loop. Since nested Python loops get notoriously slow, I was wondering if there was a better way using numpy to create the array of values that I need.
#x=max side length of brick. User Input.
for t in range(3,x):
a=[];b=[];c=[];
for u in range(2,t):
for v in range(1,u):
a.append(t)
b.append(u)
c.append(v)
a=np.array(a)
b=np.array(b)
c=np.array(c)
...
Is there a better way to generate the array af values, using numpy commands?
Thanks.
Example:
If x=10, when t=3 I want to get:
a=[3]
b=[2]
c=[1]
the first time through the loop. After that, when t=4:
a=[4, 4, 4]
b=[2, 3, 3]
c=[1, 1, 2]
The third time (t=5) I want:
a=[5, 5, 5, 5, 5, 5]
b=[2, 3, 3, 4, 4, 4]
c=[1, 1, 2, 1, 2, 3]
and so on, up to max side lengths around 5000 or so.
EDIT: Solution
a=array(3)
b=array(2)
c=array(1)
for i in range(4,x): #Removing the (3,2,1) check from code does not affect results.
foo=arange(1,i-1)
foo2=empty(len(foo))
foo2.fill(i-1)
c=hstack((c,foo))
b=hstack((b,foo2))
a=empty(len(b))
a.fill(i)
...
Works many times faster now. Thanks all.
Try to use .empty and .fill (http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.fill.html)
There are couple of things which could help, but probably only for large values of x. For starters use xrange instead of range, that will save creating a list you never need. You could also create empty numpy arrays of the correct length and fill them up with the values as you go, instead of appending to a list and then converting it into a numpy array.
I believe this code will work (no python access right this second):
for t in xrange(3, x):
size = (t - 2) * (t - 3)
a = np.zeros(size)
b = np.zeros(size)
c = np.zeros(size)
idx = 0
for u in xrange(2,t):
for v in xrange(1,u):
a[idx] = t
b[idx] = u
c[idx] = v
idx += 1
I'm sure there's a nice way to do this in Python, but I'm pretty new to the language, so forgive me if this is an easy one!
I have a list, and I'd like to pick out certain values from that list. The values I want to pick out are the ones whose indexes in the list are specified in another list.
For example:
indexes = [2, 4, 5]
main_list = [0, 1, 9, 3, 2, 6, 1, 9, 8]
the output would be:
[9, 2, 6]
(i.e., the elements with indexes 2, 4 and 5 from main_list).
I have a feeling this should be doable using something like list comprehensions, but I can't figure it out (in particular, I can't figure out how to access the index of an item when using a list comprehension).
[main_list[x] for x in indexes]
This will return a list of the objects, using a list comprehension.
t = []
for i in indexes:
t.append(main_list[i])
return t
map(lambda x:main_list[x],indexes)
If you're good with numpy:
import numpy as np
main_array = np.array(main_list) # converting to numpy array
out_array = main_array.take([2, 4, 5])
out_list = out_array.tolist() # if you want a list specifically
I think Yuval A's solution is a pretty clear and simple. But if you actually want a one line list comprehension:
[e for i, e in enumerate(main_list) if i in indexes]
As an alternative to a list comprehension, you can use map with list.__getitem__. For large lists you should see better performance:
import random
n = 10**7
L = list(range(n))
idx = random.sample(range(n), int(n/10))
x = [L[x] for x in idx]
y = list(map(L.__getitem__, idx))
assert all(i==j for i, j in zip(x, y))
%timeit [L[x] for x in idx] # 474 ms per loop
%timeit list(map(L.__getitem__, idx)) # 417 ms per loop
For a lazy iterator, you can just use map(L.__getitem__, idx). Note in Python 2.7, map returns a list, so there is no need to pass to list.
I have noticed that there are two optional ways to do this job, either by loop or by turning to np.array. Then I test the time needed by these two methods, the result shows that when dataset is large
【[main_list[x] for x in indexes]】is about 3~5 times faster than
【np.array.take()】
if your code is sensitive to the computation time, the highest voted answer is a good choice.