Handling lists in Python - python

Suppose I have a list:
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
I want to write a program that prints out all the elements of the list that are less than 10.
Actually its pretty simple I got this program but, I need to do it in a single line and I've no idea how to do that. Need some help with this.

print [x for x in a if x < 10]
Take a further look at lambda functions, I feel this is what you are looking for.

So in order to print something out of a list that is less than 10 In the same line, first you need to create a list:
numbers = []
loop through every single element of the list
for i in a:
And then you need a If statement to check if the element is less than 10
if i < 10:
Append the number to the list
numbers.append(str(i))
Join the results together:
result = " ".join(numbers)
And lastly printing it out
print(result)
And if you combine everything together, this is what you should get:
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
numbers = []
for i in a:
if i < 10:
numbers.append(str(i))
result = " ".join(numbers)
print(result)
The result should be:
1 1 2 3 5 8

Related

Returning a list of the ordered elements with a conition in while loop structure

I am trying to solve a assignment where are 13 lights and starting from 1, light is turned off at every 5th light, when the count reaches 13, start from 1st item again. The function should return the order of lights turned off. In this case, for a list of 13 items, the return list would be [5, 10, 2, 8, 1, 9, 4, 13, 12, 3, 7, 11, 6]. Also, turned off lights would not count again.
So the way I was going to approach this problem was to have a list named turnedon, which is [1,2,3,4,5,6,7,8,9,10,11,12,13] and an empty list called orderoff and append to this list whenever a light gets turned off in the turnedon list. So while the turnedon is not empty, iterate through the turnedon list and append the light getting turned off and remove that turnedoff light from the turnedon list, if that makes sense. I cannot figure out what should go into the while loop though. Any idea would be really appreciated.
def orderoff():
n=13
turnedon=[]
for n in range(1,n+1):
turnedon.append(n)
orderoff=[]
while turneon !=[]:
This problem is equivalent to the well-known Josephus problem, in which n prisoners stand in a circle, and they are killed in a sequence where each time, the next person to be killed is k steps around the circle from the previous person; the steps are only counted over the remaining prisoners. A sample solution in Python can be found on the Rosetta code website, which I've adapted slightly below:
def josephus(n, k):
p = list(range(1, n+1))
i = 0
seq = []
while p:
i = (i+k-1) % len(p)
seq.append(p.pop(i))
return seq
Example:
>>> josephus(13, 5)
[5, 10, 2, 8, 1, 9, 4, 13, 12, 3, 7, 11, 6]
This works, but the results are different from yours:
>>> pos = 0
>>> result = []
>>> while len(result) < 13 :
... pos += 5
... pos %= 13
... if pos not in result :
... result.append(pos)
...
>>> result = [i+1 for i in result] # make it 1-based, not 0-based
>>> result
[6, 11, 3, 8, 13, 5, 10, 2, 7, 12, 4, 9, 1]
>>>
I think a more optimal solution would be to use a loop, add the displacement each time, and use modules to keep the number in range
def orderoff(lights_num,step):
turnd_off=[]
num =0
for i in range(max):
num =((num+step-1)%lights_num)+1
turnd_off.append(num)
return turnd_off
print(orderoff(13))

Trying to For Loop a list and append to new list, but it returns after the first item

I'm trying to solve this task:
Loop through list A and create a new list with only items form list A that's between 0-5.
What am I doing wrong here?
a = [100, 1, 10, 2, 3, 5, 8, 13, 21, 34, 55, 98]
def new_list(x):
for item in range(len(x)):
new = []
if x[item] < 5 and x[item] > 0:
(new.append(item))
return new
print(new_list(a))
I'm just getting [1] as an answer.
You return command is inside the loop so as soon as it goes through the first case it returns the value exiting the function.
Here is an example of what your code should look like
a = [100, 1, 10, 2, 3, 5, 8, 13, 21, 34, 55, 98]
def new_list(x):
new = []
for item in range(len(x)):
if x[item] < 5 and x[item] > 0:
new.append(x[item])
return new
print new_list(a)
You can achieve the same result by using a list comprehension
def new_list(x):
return [item for item in x if 0 < item < 5]
You're resetting new to a brand new empty list each time through the loop, which discards any work done in prior iterations.
Also, in the if statement you're calling return, which exits your function immediately, so you never process the remainder of the list.
You probably wanted something like this instead:
def new_list(x):
new = []
for item in x:
if 0 < item < 5:
new.append(item)
return new
Just my recommendation. You could use filter() here instead of a making your own loop.
a = [100, 1, 10, 2, 3, 5, 8, 13, 21, 34, 55, 98]
def new_list(x, low=0, high=5):
return filter(lambda f: f in range(low, high), x)
Filter returns a new list with elements passing a given predicate and it's equivalent to
[item for item in iterable if function(item)]
as per the documentation.
Therefore
print new_list(a)
Results in:
[1, 2, 3, 5]
This way you can check any values such as:
print new_list(a, 5, 10)
[5, 8]
Three errors:
you are reinstantiating new with each iteration of the for loop.
you should return new when the list is finished building, at the end of the function.
You are appending item, but this is your index. In your code, you would have to append x[item].
Code with corrections:
a = [100, 1, 10, 2, 3, 5, 8, 13, 21, 34, 55, 98]
def new_list(x):
new = []
for item in range(len(x)):
if x[item] < 5 and x[item] > 0:
new.append(x[item])
return new
print(new_list(a))
Output:
[1, 2, 3]
Suggestions:
Don't index, loop over the items of x directly (for item in x: ...).
Use chained comparisons, e.g. 0 < item < 5.
Consider a list comprehension.
Code with all three suggestions:
>>> [item for item in a if 0 < item < 5]
>>> [1, 2, 3]
Just a suggestion!
The empty list is inside the For Loop meaning that a new empty list is created every iteration
The 'return' is also inside the for loop which is less than ideal, you want it to be returned after the loop has been exhausted and all suitable elements have been appended.
a = [100, 1, 10, 2, 3, 5, 8, 13, 21, 34, 55, 98]
def new_list(x):
new = []
for item in range(len(x)):
if x[item] < 5 and x[item] > 0:
new.append(item)
return new
print(new_list(a))

Dynamically update variables used in a For statement in python

I want to update the list used in the for loop statement as it is being appended with new values within the loop.I know this code wont update the list but I am not able to find a way to do so. I hope to required output might explain it better
INPUT
list=[1,2,3]
count=0
for x in list:
if int(len(list))>10:
break
else:
count=count+1
x=x+10
if x>3:
list=list+[x]
print "list = %r" %list
print "count = %r" %count
OUTPUT
list = [1, 2, 3, 11, 12, 13]
count = 3
Required OUTPUT
list = [1, 2, 3, 11, 12, 13, 21, 22, 23, 31]
count = 10
I suggest you use a while loop instead of a for, which saves the need of the break keyword :
l=[1,2,3]
count = len(l) # There are already len(l) elements in the list
pos = 0
while len(l) < 10:
count += 1
x = l[pos]
l.append(x+10)
pos += 1
print "list = %r" %l
print "count = %r" %count
Which gives the output :
list = [1, 2, 3, 11, 12, 13, 21, 22, 23, 31]
count = 10
Also, you can notice that i renamed the list variable to l, to prevent any confusion between the type list and the variable itself.
I used append to add elements at the end of the list.
Hope it'll be helpful.
two problems here:
first: the if x>3: test. (Why did you include that?)
second when you have a for statement, it loops on the values present initially only.
This should work:
l = [1,2,3]
count = 0
while len(l) < 10:
l.append(l[count]+10)
count += 1

Remove items from a list in Python based on previous items in the same list

Say I have a simple list of numbers, e.g.
simple_list = range(100)
I would like to shorten this list such that the gaps between the values are greater than or equal to 5 for example, so it should look like
[0, 5, 10...]
FYI the actual list does not have regular increments but it is ordered
I'm trying to use list comprehension to do it but the below obviously returns an empty list:
simple_list2 = [x for x in simple_list if x-simple_list[max(0,x-1)] >= 5]
I could do it in a loop by appending to a list if the condition is met but I'm wondering specifically if there is a way to do it using list comprehension?
This is not a use case for a comprehension, you have to use a loop as there could be any amount of elements together that have less than five between them, you cannot just check the next or any n amount of numbers unless you knew the data had some very specific format:
simple_list = range(100)
def f(l):
it = iter(l)
i = next(it)
for ele in it:
if abs(ele - i) >= 5:
yield i
i = ele
yield i
simple_list[:] = f(simple_list)
print(simple_list)
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
A better example to use would be:
l = [1, 2, 2, 2, 3, 3, 3, 10, 12, 13, 13, 18, 24]
l[:] = f(l)
print(l)
Which would return:
[1, 10, 18, 24]
If your data is always in ascending order you can remove the abs and just if ele - i >= 5.
If I understand your question correctly, which I'm not sure I do (please clarify), you can do this easily. Assume that a is the list you want to process.
[v for i,v in enumerate(a) if abs(a[i] - a[i - 1]) >= 5]
This gives all elements with which the difference to the previous one (should it be next?) are greater or equal than 5. There are some variations of this, according to what you need. Should the first element not be compared and excluded? The previous implementation compares it with index -1 and includes it if the criteria is met, this one excludes it from the result:
[v for i,v in enumerate(a) if i != 0 and abs(a[i] - a[i - 1]) >= 5]
On the other hand, should it always be included? Then use this:
[v for i,v in enumerate(a) if (i != 0 and abs(a[i] - a[i - 1]) >= 5) or (i == 0)]

Generating a list of prime numbers using list comprehension

I'm trying to create a list of all the prime numbers less than or equal to a given number. I did that successfully using for loops. I was trying to achieve the same using list comprehension using python. But my output has some unexpected values.
Here is my code..
pr=[2]
pr+=[i for i in xrange(3,num+1) if not [x for x in pr if i%x==0]]
where num is the number I had taken as input from user.
The output of the above code for
num=20 is this: [2, 3, 5, 7, 9, 11, 13, 15, 17, 19]
I'm puzzled as to why 9 and 15 are there in the output. What am I doing wrong here?
It simply doesn’t work that way. List comprehensions are evaluated separately, so you can imagine it like this:
pr = [2]
tmp = [i for i in xrange(3,num+1) if not [x for x in pr if i%x==0]]
pr += tmp
By the time tmp is evaluated, pr only contains 2, so you only ever check if a number is divisible by 2 (i.e. if it’s even). That’s why you get all uneven numbers.
You simply can’t solve this nicely† using list comprehensions.
† Not nicely, but ugly and in a very hackish way, by abusing that you can call functions inside a list comprehension:
pr = [2]
[pr.append(i) for i in xrange(3,num+1) if not [x for x in pr if i%x==0]]
print(pr) # [2, 3, 5, 7, 11, 13, 17, 19]
This abuses list comprehensions and basically collects a None value for each prime number you add to pr. So it’s essentially like your normal for loop except that we unnecessarily collect None values in a list… so you should rather allow yourself to use a line break and just use a normal loop.
Your list pr doesn't update until after your entire list comprehension is done. This means your list only contains 2, so every number dividable by 2 is not in the list (as you can see). You should update the list whenever you found a new prime number.
This is because the pr += [...] is evaluated approximately as this:
pr = [2]
tmp = [i for i in xrange(3,num+1) if not [x for x in pr if i%x==0]]
pr.extend(tmp)
So while tmp is generated, contents of pr remains the same ([2]).
I would go with function like this:
>>> import itertools
>>> def primes():
... results = []
... for i in itertools.count(2):
... if all(i%x != 0 for x in results):
... results.append(i)
... yield i
...
# And then you can fetch first 10 primes
>>> list(itertools.islice(primes(), 10))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
# Or get primes smaller than X
>>> list(itertools.takewhile(lambda x: x < 50, primes()))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
Note, that using all is more efficient than creating array and testing whether it's empty.

Categories

Resources